5.编写一个程序,提示用户输入一个字符串。然后该程序把该字符串的字符逐个压入一个栈(参见复习题5),然后从栈中弹出这些字符,并显示它们。结果显示为该字符串的逆序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_SIZE 1000
// 栈结构定义
typedef struct {
char items[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack* stack) {
stack->top = -1;
}
// 检查栈是否为空
int isEmpty(Stack* stack) {
return stack->top == -1;
}
// 检查栈是否已满
int isFull(Stack* stack) {
return stack->top == MAX_SIZE - 1;
}
// 将字符压入栈
void push(Stack* stack, char item) {
if (isFull(stack)) {
printf("栈已满,无法压入更多元素!\n");
return;
}
stack->items[++stack->top] = item;
}
// 从栈中弹出字符
char pop(Stack* stack) {
if (isEmpty(stack)) {
printf("栈为空,无法弹出元素!\n");
return '\0';
}
return stack->items[stack->top--];
}
// 获取栈的大小
int size(Stack* stack) {
return stack->top + 1;
}
// 使用栈反转字符串
void reverseStringWithStack(char* input, char* output) {
Stack stack;
initStack(&stack);
// 将字符串中的每个字符逐个压入栈中
int len = strlen(input);
for (int i = 0; i < len; i++) {
push(&stack, input[i]);
}
// 从栈中弹出字符并构建反转后的字符串
int index = 0;
while (!isEmpty(&stack)) {
output[index++] = pop(&stack);
}
output[index] = '\0'; // 添加字符串结束符
}
int main() {
system("chcp 65001");
char input[MAX_SIZE];
char reversed[MAX_SIZE];
// 提示用户输入字符串
printf("请输入一个字符串: ");
fgets(input, sizeof(input), stdin);
// 移除可能的换行符
int len = strlen(input);
if (len > 0 && input[len - 1] == '\n') {
input[len - 1] = '\0';
}
// 使用栈反转字符串
reverseStringWithStack(input, reversed);
// 显示结果
printf("原字符串: %s\n", input);
printf("反转后字符串: %s\n", reversed);
return 0;
}
6.编写一个函数接受3个参数:一个数组名(内含已排序的整数)、该数组的元素个数和待查找的整数。如果待查找的整数在数组中,那么该函数返回1;如果该数不在数组中,该函数则返回0。用二分查找法实现。
int binarySearch(int arr[], int n, int target) {
int left = 0;
int right = n - 1;
while (left <= right) {
int mid = left + (right - left) / 2; // 防止整数溢出
if (arr[mid] == target) {
return 1; // 找到目标值,返回1
}
else if (arr[mid] < target) {
left = mid + 1; // 在右半部分查找
}
else {
right = mid - 1; // 在左半部分查找
}
}
return 0; // 未找到目标值,返回0
}
int main() {
system("chcp 65001");
int arr[] = { 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 };
int n = sizeof(arr) / sizeof(arr[0]);
// 测试查找存在的元素
printf("查找 7: %d\n", binarySearch(arr, n, 7)); // 应该输出 1
printf("查找 1: %d\n", binarySearch(arr, n, 1)); // 应该输出 1
printf("查找 19: %d\n", binarySearch(arr, n, 19)); // 应该输出 1
// 测试查找不存在的元素
printf("查找 4: %d\n", binarySearch(arr, n, 4)); // 应该输出 0
printf("查找 20: %d\n", binarySearch(arr, n, 20)); // 应该输出 0
return 0;
}
7.编写一个程序,打开和读取一个文本文件,并统计文件中每个单词出现的次数。用改进的二叉查找树存储单词及其出现的次数。程序在读入文件后,会提供一个有3个选项的菜单。第1个选项是列出所有的单词和出现的次数。第2个选项是让用户输入一个单词,程序报告该单词在文件中出现的次数。第3个选项是退出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// 改进的二叉查找树节点结构
typedef struct TreeNode {
char word[100];
int count;
struct TreeNode* left;
struct TreeNode* right;
} TreeNode;
// 创建新节点
TreeNode* createNode(const char* word) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
if (newNode == NULL) {
printf("内存分配失败\n");
exit(1);
}
strcpy_s(newNode->word, word);
newNode->count = 1;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// 插入单词到二叉查找树
TreeNode* insertWord(TreeNode* root, const char* word) {
if (root == NULL) {
return createNode(word);
}
int cmp = strcmp(word, root->word);
if (cmp == 0) {
root->count++;
}
else if (cmp < 0) {
root->left = insertWord(root->left, word);
}
else {
root->right = insertWord(root->right, word);
}
return root;
}
// 中序遍历打印所有单词和计数(按字典顺序)
void printAllWords(TreeNode* root) {
if (root != NULL) {
printAllWords(root->left);
printf("%s: %d\n", root->word, root->count);
printAllWords(root->right);
}
}
// 查找单词出现次数
int findWordCount(TreeNode* root, const char* word) {
if (root == NULL) {
return 0;
}
int cmp = strcmp(word, root->word);
if (cmp == 0) {
return root->count;
}
else if (cmp < 0) {
return findWordCount(root->left, word);
}
else {
return findWordCount(root->right, word);
}
}
// 释放二叉查找树内存
void freeTree(TreeNode* root) {
if (root != NULL) {
freeTree(root->left);
freeTree(root->right);
free(root);
}
}
// 清理单词字符串(转换为小写并移除标点符号)
void cleanWord(char* word) {
int i, j = 0;
char cleaned[100];
// 转换为小写并移除标点符号
for (i = 0; word[i] != '\0'; i++) {
if (isalpha(word[i])) {
cleaned[j++] = tolower(word[i]);
}
}
cleaned[j] = '\0';
// 复制回原字符串
strcpy_s(word, 100, cleaned);
}
// 从文件读取并处理单词
TreeNode* processFile(const char* filename) {
FILE* file;
fopen_s(&file, filename, "r");
if (file == NULL) {
printf("无法打开文件: %s\n", filename);
return NULL;
}
TreeNode* root = NULL;
char word[100];
// 读取文件中的每个单词
while (fscanf_s(file, "%s", word, 100) != EOF) {
cleanWord(word);
if (strlen(word) > 0) {
root = insertWord(root, word);
}
}
fclose(file);
printf("文件读取完成。\n");
return root;
}
// 显示菜单
void showMenu() {
printf("\n========== 单词计数程序 ==========\n");
printf("1. 列出所有单词和出现次数\n");
printf("2. 查询特定单词的出现次数\n");
printf("3. 退出程序\n");
printf("=================================\n");
printf("请选择操作 (1-3): ");
}
int main() {
system("chcp 65001");
char filename[100];
TreeNode* root = NULL;
printf("请输入要读取的文本文件名: ");
scanf_s("%s", filename, 100);
// 读取和处理文件
root = processFile(filename);
if (root == NULL) {
return 1;
}
int choice;
do {
showMenu();
if (scanf_s("%d", &choice) != 1) {
printf("输入无效,请输入数字 1-3。\n");
while (getchar() != '\n'); // 清空输入缓冲区
continue;
}
switch (choice) {
case 1:
if (root == NULL) {
printf("没有单词数据。\n");
}
else {
printf("单词统计结果:\n");
printAllWords(root);
}
break;
case 2: {
char searchWord[100];
printf("请输入要查询的单词: ");
scanf_s("%s", searchWord, 100);
cleanWord(searchWord);
int count = findWordCount(root, searchWord);
if (count > 0) {
printf("单词 \"%s\" 在文件中出现了 %d 次。\n", searchWord, count);
}
else {
printf("单词 \"%s\" 在文件中未找到。\n", searchWord);
}
break;
}
case 3:
printf("感谢使用单词计数程序!\n");
break;
default:
printf("无效选择,请输入 1-3 之间的数字。\n");
}
} while (choice != 3);
// 释放内存
freeTree(root);
return 0;
}
8.修改宠物俱乐部程序,把所有同名的宠物都存储在同一个节点中。当用户选择查找宠物时,程序应询问用户该宠物的名字,然后列出该名字的所有宠物(及其种类)。
tree.h
// tree.h - 修改后的头文件
/* tree.h -- binary search tree */
/* no duplicate items are allowed in this tree */
#ifndef _TREE_H_
#define _TREE_H_
#include <stdbool.h>
/* redefine Item as appropriate */
#define SLEN 20
typedef struct item
{
char petname[SLEN];
char petkind[SLEN];
} Item;
#define MAXITEMS 10
typedef struct trnode
{
Item items[MAXITEMS]; // 存储多个同名宠物
int count; // 当前节点中宠物的数量
struct trnode * left; /* pointer to right branch */
struct trnode * right; /* pointer to left branch */
} Trnode;
typedef struct tree
{
Trnode * root; /* pointer to root of tree */
int size; /* number of items in tree */
} Tree;
/* function prototypes */
/* operation: initialize a tree to empty */
/* preconditions: ptree points to a tree */
/* postconditions: the tree is initialized to empty */
void InitializeTree(Tree * ptree);
/* operation: determine if tree is empty */
/* preconditions: ptree points to a tree */
/* postconditions: function returns true if tree is */
/* empty and returns false otherwise */
bool TreeIsEmpty(const Tree * ptree);
/* operation: determine if tree is full */
/* preconditions: ptree points to a tree */
/* postconditions: function returns true if tree is */
/* full and returns false otherwise */
bool TreeIsFull(const Tree * ptree);
/* operation: determine number of items in tree */
/* preconditions: ptree points to a tree */
/* postconditions: function returns number of items in */
/* tree */
int TreeItemCount(const Tree * ptree);
/* operation: add an item to a tree */
/* preconditions: pi is address of item to be added */
/* ptree points to an initialized tree */
/* postconditions: if possible, function adds item to */
/* tree and returns true; otherwise, */
/* the function returns false */
bool AddItem(const Item * pi, Tree * ptree);
/* operation: find an item in a tree */
/* preconditions: pi points to an item */
/* ptree points to an initialized tree */
/* postconditions: function returns true if item is in */
/* tree and returns false otherwise */
bool InTree(const Item * pi, const Tree * ptree);
/* operation: find all pets with the same name */
/* preconditions: pname points to pet name */
/* ptree points to an initialized tree */
/* postconditions: prints all pets with given name */
void FindPetsByName(const Tree * ptree, const char * pname);
/* operation: delete an item from a tree */
/* preconditions: pi is address of item to be deleted */
/* ptree points to an initialized tree */
/* postconditions: if possible, function deletes item */
/* from tree and returns true; */
/* otherwise the function returns false*/
bool DeleteItem(const Item * pi, Tree * ptree);
/* operation: apply a function to each item in */
/* the tree */
/* preconditions: ptree points to a tree */
/* pfun points to a function that takes*/
/* an Item argument and has no return */
/* value */
/* postcondition: the function pointed to by pfun is */
/* executed once for each item in tree */
void Traverse (const Tree * ptree, void (* pfun)(Item item));
/* operation: delete everything from a tree */
/* preconditions: ptree points to an initialized tree */
/* postconditions: tree is empty */
void DeleteAll(Tree * ptree);
#endif
tree.c
// tree.c - 修改后的实现文件
/* tree.c -- tree support functions */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "tree.h"
/* local data type */
typedef struct pair {
Trnode* parent;
Trnode* child;
} Pair;
/* prototypes for local functions */
static Trnode* MakeNode(const Item* pi);
static bool ToLeft(const char* name1, const char* name2);
static bool ToRight(const char* name1, const char* name2);
static void AddNode(Trnode* new_node, Trnode* root);
static void InOrder(const Trnode* root, void (*pfun)(Item item));
static Pair SeekItem(const Item* pi, const Tree* ptree);
static Trnode* SeekNodeByName(const char* pname, const Tree* ptree);
static void DeleteNode(Trnode** ptr);
static void DeleteAllNodes(Trnode* ptr);
/* function definitions */
void InitializeTree(Tree* ptree)
{
ptree->root = NULL;
ptree->size = 0;
}
bool TreeIsEmpty(const Tree* ptree)
{
if (ptree->root == NULL)
return true;
else
return false;
}
bool TreeIsFull(const Tree* ptree)
{
if (ptree->size == MAXITEMS)
return true;
else
return false;
}
int TreeItemCount(const Tree* ptree)
{
return ptree->size;
}
bool AddItem(const Item* pi, Tree* ptree)
{
Trnode* new_node;
Trnode* found_node;
if (TreeIsFull(ptree))
{
fprintf(stderr, "Tree is full\n");
return false;
}
// 查找是否已存在同名宠物
found_node = SeekNodeByName(pi->petname, ptree);
if (found_node != NULL)
{
// 如果节点未满,添加到现有节点
if (found_node->count < MAXITEMS)
{
found_node->items[found_node->count] = *pi;
found_node->count++;
ptree->size++;
return true;
}
else
{
fprintf(stderr, "No room for more pets with that name\n");
return false;
}
}
// 创建新节点
new_node = MakeNode(pi);
if (new_node == NULL)
{
fprintf(stderr, "Couldn't create node\n");
return false;
}
ptree->size++;
if (ptree->root == NULL)
ptree->root = new_node;
else
AddNode(new_node, ptree->root);
return true;
}
bool InTree(const Item* pi, const Tree* ptree)
{
Trnode* found_node;
found_node = SeekNodeByName(pi->petname, ptree);
if (found_node == NULL)
return false;
// 检查该节点中是否有完全匹配的宠物
for (int i = 0; i < found_node->count; i++)
{
if (strcmp(found_node->items[i].petkind, pi->petkind) == 0)
return true;
}
return false;
}
void FindPetsByName(const Tree* ptree, const char* pname)
{
Trnode* found_node;
char upper_name[SLEN];
strcpy_s(upper_name, pname);
// 转换为大写以匹配存储格式
for (int i = 0; upper_name[i]; i++)
upper_name[i] = toupper(upper_name[i]);
found_node = SeekNodeByName(upper_name, ptree);
if (found_node == NULL)
{
printf("No pets named %s found.\n", pname);
return;
}
printf("Pets named %s:\n", pname);
for (int i = 0; i < found_node->count; i++)
{
printf(" Kind: %s\n", found_node->items[i].petkind);
}
}
bool DeleteItem(const Item* pi, Tree* ptree)
{
Pair look;
Trnode* found_node;
found_node = SeekNodeByName(pi->petname, ptree);
if (found_node == NULL)
return false;
// 在节点中查找特定种类的宠物
int index = -1;
for (int i = 0; i < found_node->count; i++)
{
if (strcmp(found_node->items[i].petkind, pi->petkind) == 0)
{
index = i;
break;
}
}
if (index == -1)
return false;
// 从节点中移除该项
for (int i = index; i < found_node->count - 1; i++)
{
found_node->items[i] = found_node->items[i + 1];
}
found_node->count--;
ptree->size--;
// 如果节点为空,删除节点
if (found_node->count == 0)
{
look = SeekItem(pi, ptree);
if (look.parent == NULL)
DeleteNode(&ptree->root);
else if (look.parent->left == look.child)
DeleteNode(&look.parent->left);
else
DeleteNode(&look.parent->right);
}
return true;
}
void Traverse(const Tree* ptree, void (*pfun)(Item item))
{
if (ptree != NULL)
InOrder(ptree->root, pfun);
}
void DeleteAll(Tree* ptree)
{
if (ptree != NULL)
DeleteAllNodes(ptree->root);
ptree->root = NULL;
ptree->size = 0;
}
/* local functions */
static void InOrder(const Trnode* root, void (*pfun)(Item item))
{
if (root != NULL)
{
InOrder(root->left, pfun);
for (int i = 0; i < root->count; i++)
(*pfun)(root->items[i]);
InOrder(root->right, pfun);
}
}
static void DeleteAllNodes(Trnode* root)
{
Trnode* pright;
if (root != NULL)
{
pright = root->right;
DeleteAllNodes(root->left);
free(root);
DeleteAllNodes(pright);
}
}
static void AddNode(Trnode* new_node, Trnode* root)
{
if (ToLeft(new_node->items[0].petname, root->items[0].petname))
{
if (root->left == NULL)
root->left = new_node;
else
AddNode(new_node, root->left);
}
else if (ToRight(new_node->items[0].petname, root->items[0].petname))
{
if (root->right == NULL)
root->right = new_node;
else
AddNode(new_node, root->right);
}
else
{
fprintf(stderr, "location error in AddNode()\n");
exit(1);
}
}
static bool ToLeft(const char* name1, const char* name2)
{
if (strcmp(name1, name2) < 0)
return true;
else
return false;
}
static bool ToRight(const char* name1, const char* name2)
{
if (strcmp(name1, name2) > 0)
return true;
else
return false;
}
static Trnode* MakeNode(const Item* pi)
{
Trnode* new_node;
new_node = (Trnode*)malloc(sizeof(Trnode));
if (new_node != NULL)
{
new_node->items[0] = *pi;
new_node->count = 1;
new_node->left = NULL;
new_node->right = NULL;
}
return new_node;
}
static Pair SeekItem(const Item* pi, const Tree* ptree)
{
Pair look;
look.parent = NULL;
look.child = ptree->root;
if (look.child == NULL)
return look;
while (look.child != NULL)
{
if (ToLeft(pi->petname, look.child->items[0].petname))
{
look.parent = look.child;
look.child = look.child->left;
}
else if (ToRight(pi->petname, look.child->items[0].petname))
{
look.parent = look.child;
look.child = look.child->right;
}
else
break;
}
return look;
}
static Trnode* SeekNodeByName(const char* pname, const Tree* ptree)
{
Trnode* current = ptree->root;
while (current != NULL)
{
int comp = strcmp(pname, current->items[0].petname);
if (comp == 0)
return current;
else if (comp < 0)
current = current->left;
else
current = current->right;
}
return NULL;
}
static void DeleteNode(Trnode** ptr)
{
Trnode* temp;
if ((*ptr)->left == NULL)
{
temp = *ptr;
*ptr = (*ptr)->right;
free(temp);
}
else if ((*ptr)->right == NULL)
{
temp = *ptr;
*ptr = (*ptr)->left;
free(temp);
}
else
{
for (temp = (*ptr)->left; temp->right != NULL;
temp = temp->right)
continue;
temp->right = (*ptr)->right;
temp = *ptr;
*ptr = (*ptr)->left;
free(temp);
}
}
petclub.c
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "tree.h"
char menu(void);
void addpet(Tree* pt);
void droppet(Tree* pt);
void showpets(const Tree* pt);
void findpet(const Tree* pt);
void printitem(Item item);
void uppercase(char* str);
char* s_gets(char* st, int n);
int main(void)
{
Tree pets;
char choice;
InitializeTree(&pets);
while ((choice = menu()) != 'q')
{
switch (choice)
{
case 'a': addpet(&pets);
break;
case 'l': showpets(&pets);
break;
case 'f': findpet(&pets);
break;
case 'n': printf("%d pets in club\n",
TreeItemCount(&pets));
break;
case 'd': droppet(&pets);
break;
default: puts("Switching error");
}
}
DeleteAll(&pets);
puts("Bye.");
return 0;
}
char menu(void)
{
int ch;
puts("Nerfville Pet Club Membership Program");
puts("Enter the letter corresponding to your choice:");
puts("a) add a pet l) show list of pets");
puts("n) number of pets f) find pets");
puts("d) delete a pet q) quit");
while ((ch = getchar()) != EOF)
{
while (getchar() != '\n') /* discard rest of line */
continue;
ch = tolower(ch);
if (strchr("alrfndq", ch) == NULL)
puts("Please enter an a, l, f, n, d, or q:");
else
break;
}
if (ch == EOF) /* make EOF cause program to quit */
ch = 'q';
return ch;
}
void addpet(Tree* pt)
{
Item temp;
if (TreeIsFull(pt))
puts("No room in the club!");
else
{
puts("Please enter name of pet:");
s_gets(temp.petname, SLEN);
puts("Please enter pet kind:");
s_gets(temp.petkind, SLEN);
uppercase(temp.petname);
uppercase(temp.petkind);
AddItem(&temp, pt);
}
}
void showpets(const Tree* pt)
{
if (TreeIsEmpty(pt))
puts("No entries!");
else
Traverse(pt, printitem);
}
void printitem(Item item)
{
printf("Pet: %-19s Kind: %-19s\n", item.petname,
item.petkind);
}
void findpet(const Tree* pt)
{
char pname[SLEN];
if (TreeIsEmpty(pt))
{
puts("No entries!");
return;
}
puts("Please enter name of pet you wish to find:");
s_gets(pname, SLEN);
FindPetsByName(pt, pname);
}
void droppet(Tree* pt)
{
Item temp;
if (TreeIsEmpty(pt))
{
puts("No entries!");
return;
}
puts("Please enter name of pet you wish to delete:");
s_gets(temp.petname, SLEN);
puts("Please enter pet kind:");
s_gets(temp.petkind, SLEN);
uppercase(temp.petname);
uppercase(temp.petkind);
printf("%s the %s ", temp.petname, temp.petkind);
if (DeleteItem(&temp, pt))
printf("is dropped from the club.\n");
else
printf("is not a member.\n");
}
void uppercase(char* str)
{
while (*str)
{
*str = toupper(*str);
str++;
}
}
char* s_gets(char* st, int n)
{
char* ret_val;
char* find;
ret_val = fgets(st, n, stdin);
if (ret_val)
{
find = strchr(st, '\n'); // look for newline
if (find) // if the address is not NULL,
*find = '\0'; // place a null character there
else
while (getchar() != '\n')
continue; // dispose of rest of line
}
return ret_val;
}