问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

求利用c\c++将字符串集构建成一棵树的程序代码

发布网友 发布时间:2022-10-17 23:26

我来回答

1个回答

热心网友 时间:2023-11-04 16:43

表达式树是树结构的一个经典应用。

常见的表达式:3+5*7+2为中缀表达式。

这里,我实现一种转换算法,那就是先把中缀式子转化为一棵树,然后使用不同的遍历遍历方式得到不同的表达式

【注】(仅仅给出没有括号时的代码,为了简化字符串处理,我没有使用字符串,而是使用了字符,因此不支持两位的数字算式)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct string_node {
char tag; //定义字符
struct string_node *left;
struct string_node *right;
struct string_node *parent;
};
struct string_node *gen_sub_tree(char*str, int len)
{
struct string_node *root;
int i = 0;
for (i = 0; i < len; i++) {
struct string_node *node = (struct string_node*)calloc(1, sizeof(structstring_node));
node->tag =str[i];
if(isdigit(str[i])) {
if (i != 0) {//运算由左至右,除了第一个操作数,其它全部为右操作数,高优先级的会处在树的旁支
root->right = node;
node->parent = root;
}
root = node;
} else if((str[i] == 'x') || (str[i] == '/')) {
//处理乘除运算符
struct string_node *temp_root = NULL, *temp_parent = NULL;
if (root->parent &&(root->parent->tag == '+' || root->parent->tag == '-')) {
temp_parent = root->parent;
temp_root = root;
} else if(root->parent) {
temp_parent =root->parent->parent;
temp_root = root->parent;
} else {
temp_root = root;
}
node->parent = temp_parent;
if (temp_parent)
temp_parent->right = node;
node->left = temp_root;
temp_root->parent = node;
root = node;
} else if (str[i] == '+' || str[i] == '-') {
//处理加减运算符
struct string_node *temp_root =NULL, *temp_parent = NULL;
if (root->parent &&root->parent->parent &&(root->parent->tag == 'x' || root->parent->tag == '/')) {
temp_root =root->parent->parent;
} else if (root->parent&& !root->parent->parent){
temp_root = root->parent;
} else {
temp_root = root;
}
node->left = temp_root;
temp_root->parent = node;
root = node;
}
}
//找到树根,返回调用者
while (root->parent) {
root = root->parent;
}
return root;
}
int main(int argc, char **argv)
{
struct string_node *root;
char str[40] ={'1','+','0','+','2','x','5','+','3','x','4','x','2', '-', '7'};
root = NULL;
root = gen_sub_tree(str, 100);
print_result(root);
return 0;
}
//输出结果
void print_result(struct string_node*p)
{
if(p != NULL) {
//此为后缀表达式,根据printf的位置不同可以得到不同的X缀表达式
print_result(p->left);
print_result(p->right);
printf("%c\n", p->tag);
}
}

【】下面考虑加上括号时的情况,由于号优先级最高,而且还不是像运算符那样结合操作数的字符,因此把括号括住的成分单独作为一个操作数比较好,这样就可以递归的实现了。,只需要加入对’(‘和’)’的解析即可喽,递归调用gen_sub_tree即可。以下为加入括号处理的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct string_node {
char tag; //定义字符
struct string_node *left;
struct string_node *right;
struct string_node *parent;
};
struct string_node *gen_sub_tree(char*str, int len)
{
struct string_node *root;
int i = 0;
for (i = 0; i < len; i++) {
struct string_node *node = (struct string_node*)calloc(1, sizeof(structstring_node));
node->tag =str[i];
if(isdigit(str[i])) {
if (i != 0) {//运算由左至右,除了第一个操作数,其它全部为右操作数,高优先级的会处在树的旁支
root->right = node;
node->parent = root;
}
root = node;
} else if((str[i] == 'x') || (str[i] == '/')) {
//处理乘除运算符
struct string_node *temp_root = NULL, *temp_parent = NULL;
if (root->parent &&(root->parent->tag == '+' || root->parent->tag == '-')) {
temp_parent = root->parent;
temp_root = root;
} else if(root->parent) {
temp_parent =root->parent->parent;
temp_root = root->parent;
} else {
temp_root = root;
}
node->parent = temp_parent;
if (temp_parent)
temp_parent->right = node;
node->left = temp_root;
temp_root->parent = node;
root = node;
} else if (str[i] == '+' || str[i] == '-') {
//处理加减运算符
struct string_node *temp_root =NULL, *temp_parent = NULL;
if (root->parent &&root->parent->parent &&(root->parent->tag == 'x' || root->parent->tag == '/')) {
temp_root =root->parent->parent;
} else if (root->parent&& !root->parent->parent){
temp_root = root->parent;
} else {
temp_root = root;
}
node->left = temp_root;
temp_root->parent = node;
root = node;
}
}
//找到树根,返回调用者
while (root->parent) {
root = root->parent;
}
return root;
}
int main(int argc, char **argv)
{
struct string_node *root;
char str[40] ={'1','+','0','+','2','x','5','+','3','x','4','x','2', '-', '7'};
root = NULL;
root = gen_sub_tree(str, 100);
print_result(root);
return 0;
}
//输出结果
void print_result(struct string_node*p)
{
if(p != NULL) {
//此为后缀表达式,根据printf的位置不同可以得到不同的X缀表达式
print_result(p->left);
print_result(p->right);
printf("%c\n", p->tag);
}
}
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
非消防专业考消防工程师条件 二级消防工程师专业不对口能考吗 非专业消防工程师报考条件是什么 不是消防专业怎么报考消防证 考消防工程师必须专业对口吗 专业不对口可以报考一级消防工程师吗 苹果手机屏幕亮度怎么设置最佳 oled手机关灯亮度调到多少 keyshot渲染如何渲染好看 给文玩核桃起个店名子 火龙果馒头怎么保持颜色不变 火龙果做馒头蒸完不变色窍门 vb程序小名今年15岁,他在今年生日的这一天种了1棵树。求代码!!! u盘不能格式化怎么办 格式化方法步骤 永诺家闪光灯有和尼康SB5000同级别的吗? 就像永诺600二代对应佳能600ex二代一样 电磁炉不检锅的维修方法 电磁炉不检锅怎么维修 WOW 怎么移动聊天框的位置 魔兽聊天框下拉显示最底部 - 信息提示 话赞美祖国强大 中餐点菜三优四忌指什么 盒马鲜生每日没有卖出的肉类海鲜怎么办? 百度云盘在,分享一个文档时,如何防止其他文件不被访问 走路磨脚掌什么原因 右脚走路磨地,是什么病? 脚掌走路磨了炮怎么办 隐约造句-用隐约造句 幽僻的意思 用过了iphoneX要用iphone11是吗? iphonex有必要换11吗 怎样才知道他喜不喜欢你? c++用代码创建一棵二叉树,不是靠人为输入那种 忘仙安卓版,免罪金牌多少钱? 沙棘茶的副作用与禁忌 沙棘茶的禁忌有哪些 手机怎么查社保卡余额?社保卡丢了怎么办 我说话,不知道为什么,老感觉喘不过气来,尤其是开口说话第一句时和说话快时,怎么办?我应该怎么练习 说话喘不上气还结巴怎么改?一个字能重复好几遍,想说的话卡在嗓子眼里说不出来。怎么办 讲话就喘气透不过气乎呼吸困难 明察暗访造句 彻底解决老鼠进发动机的方法是什么 manage的同义词 全新一代骁龙8是什么型号的处理器? 没绑定手机号,密码忘了怎么找回 我有个vivo手机,有,但没有手机号,忘记了密码,该怎么办? 我只有,没有手机号码也忘记密码了,请问微信该怎么登录? 没绑定手机号,密码忘了怎么找回? 我有个vivo手机,有,但没有手机号,忘记了密码,该怎么办? 我只有,没有手机号码也忘记密码了,请问微信该怎么登录? 2017冰箱行业十大品牌 求七年间的爱的钢琴谱 求林峰 我们很好,爱在记忆中找你,爱不疚这三首的钢琴谱 ..