C语言编程实例——实现了几种常见的字符串处理情况

        一个综合性的C语言字符串编程题目,题目各项要求都使用到了比较经常遇到的各种字符串相关操作,比如:字符串分割、字符串拼接、字符串赋值、字符串转整数等


题目介绍:

有字符串s,满足如下要求:

  1. 字符串s仅允许小写字母、大写字母、数字[0-9]、加号、减号共26+26+10+2=64种符号;
  2. 加号、减号后继字符只允许数字;
  3. 从字符串s中取任意连续的字符组成的整数子串,称为s的子整数,如:0, 5, 8, 003, 202, +5, +8, +003, +202, -5, -8, -003, -202;
  4. 对字符串s,顺次不漏提取一组子整数,构成一个s的一个子整数组合;一个字符串s可以对应多个子整数组合;

编写程序,满足下列功能要求:

  1. 字符串输入:从键盘输入一个任意长度的字符串;
  2. 判断合法性:如果字符串不符合上述要求,接受字符串并提示,否则拒绝并提示;
  3. 字符统计:按照ASCII字符顺序统计字符串字符频次,并显示,未出现的字符不统计;
  4. 列举字符串的所有的子整数组合,并显示:
  5. 求解和最小的子整数组合,并显示;
  6. 按和的升序列举所有的子整数组合,并显示。

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int flag;
int add = 0;

void Init(char s[]) //检查输入
{
    int i = 1;
	for(i = 0; i < strlen(s); i ++)
	{
		if((s[i] >= 'a' && s[i] <= 'z') || (s[i] == '-') || (s[i] == '+') || (s[i] >= '0' && s[i] <= '9') || (s[i] >= 'A' && s[i] <= 'Z'))
		{
			if((s[i] == '-') || (s[i] == '+'))
			{

				if(s[i+1] < '0' || s[i+1] > '9')
				{
					flag = 0;
					return ;
				}
			}
		}
		else
		{
			flag = 0;
			return ;
		}
	}

	return ;
}

void Count(char s[])  //统计各字母出现频率
{
	int sum[64] = {0}; //按照ASCII码顺序存储64个字符出现频率
    int i;
	for(i = 0; i < strlen(s); i ++)
	{
		if((s[i] == '-') || (s[i] == '+'))
		{
			if(s[i] == '+')
			{
				sum[0] ++;
				add ++;
			}
			else if(s[i] == '-')
			{
				sum[1] ++;
				add ++;
			}
		}
		else if((s[i] >= '0' && s[i] <= '9'))
		{
			int temp = s[i] - 47;
			sum[1 + temp] ++;
		}
		else if((s[i] >= 'A' && s[i] <= 'Z'))
		{
			int temp = s[i] - 64;
			sum[11 + temp] ++;
		}
		else if((s[i] >= 'a' && s[i] <= 'z'))
		{
			int temp = s[i] - 96;
			sum[37 + temp] ++;
		}
		else
		{
			printf("Error!\n");
			return ;
		}
	}
	printf("The word frequency is as follows:\n");

	for(i = 0;i < 64; i++)
	{
		if(sum[i] != 0)
		{
			if(i == 0)
			{
				printf(" + : %d\n",sum[i]);
			}
			else if(i == 1)
			{
				printf(" - : %d\n",sum[i]);
			}
			else if(i >= 2 && i <= 11)
			{
				printf(" %d ",i-2);
				printf(": %d\n",sum[i]);
			}
			else if(i >= 12 && i <= 37)
			{
				char temp;
				temp = (char)(i+53);
				printf(" %c : %d\n",temp,sum[i]);
			}
			else if(i >= 38 && i <= 63)
			{
				char temp;
				temp = (char)(i+59);
				printf(" %c : %d\n",temp,sum[i]);
			}
		}
	}
	printf("\n");
	return ;
}

void Display(char *str[],int number[],int m) //输出所有子整数组合,输出和最大的子整数组合,子整数组合排序并输出
{
	int min = number[0];
	char temp_str[999]; 	//这里必须设置成char[]类型,char*不行,否则下面strcpy和strcat函数没法用,主要要设置大小,我这里给的999,根据自己需求给
	char min_str[999];		//同上,这部分也卡了我挺久的
	int temp;
	char str_sort[999][999]={0};
	int sum_add[999]={0};
	int sum_sort[999]={0};
	int n = 0;
	strcpy(min_str,str[0]);
	printf("All combinations are as follows:\n");
	int i;
	int j;
	for(i = 0; i < m;i++)
	{
		temp = number[i];
		strcpy(temp_str,str[i]);
		strcpy(str_sort[n],temp_str);
		sum_add[n] = temp;
		sum_sort[n] = temp;
		n++;
		printf("%s\n",temp_str);
		if(temp < min)
		{
			min = temp;
			strcpy(min_str,temp_str);
		}
		for(j = i + 1; j < m;j++)
		{
			temp = temp + number[j];
			strcat(temp_str,str[j]);
			strcpy(str_sort[n],temp_str);
			sum_add[n] = temp;
			sum_sort[n] = temp;
			n++;
			printf("%s\n",temp_str);
			if(temp < min)
			{
				min = temp;
				strcpy(min_str,temp_str);
			}
		}
	}
	printf("\n");
	printf("String of minimum sum: ");
	printf("%s\n",min_str);
	printf("\n");
	int t;
	int f[n];
	for (j = 0; j < n -1; j++) //根据子整数组合求和大小进行顺序排序
    {
        for (i = 0; i < n-j-1; i++)
        if (sum_sort[i] > sum_sort[i + 1])//比较
        {
            t = sum_sort[i];
            sum_sort[i] = sum_sort[i + 1];
            sum_sort[i + 1] = t;//换位
        }
    }
	printf("Sorted results:\n");
	for(i = 0;i < n;i++)
	{
		for(j = 0;j < n;j++)
		{
			if(sum_add[j] == sum_sort[i] && f[j] != 1)
			{
				printf("%s\n",str_sort[j]);
				f[j] = 1;
			}
		}
	}

	return ;
}

void Extract(char s[]) //拆分输入的字符串,剔除其中的字母字符
{
	char new_s[strlen(s) + add + 1];  //这块卡了我好久,一开始因为大小未知,就没设置大小,编译器也没报错,但是下面代码运行到下面的语句,寄存器就会错乱
	int number[9999] = {0};
	char *new_str[9999] = {'\0'};
	int m = 0;
	int j = 0;
	int i = 0;
	memset(new_s, 0 ,sizeof(new_s));
	while(i < strlen(s)) //就是这个循环,没设置字符数组大小,变量i给我乱跳,debug了好久都弄不清楚为啥乱跳,最后终于弄明白了,就是上面提到的原因
	{
		if((s[i] < '0' || s[i] > '9') && (s[i] != '-') && (s[i] != '+'))
		{
			new_s[j++] = ',';
			i++;
		}
		else if(s[i] == '-' || s[i] == '+')
		{
			new_s[j++] = ',';
			new_s[j++] = s[i++];
		}
		else
		{
			new_s[j++] = s[i++];
		}
	}
	char *token;
	char *tt;
	const char c[2] = ",";
	int value;
	token = strtok( new_s , c);
	while(token != NULL)
	{
		value = strtol(token,&tt,10);
		if( tt != token)
		{
			number[m] = value;
			new_str[m] = token;
			m++;
		}

		// if(atoi(token) != 0)
		// {
		// 	number[m] = atoi(token);
		// 	new_str[m] = token;
		// 	m++;
		// }
		token = strtok(NULL,c);
	}
	Display(new_str,number,m);
	return ;
}

int main()
{
	char s[9999] = {0};
	flag = 1;
	gets(s);
	Init(s);
	if(flag == 1)
	{
		printf("input success!\n");
		printf("\n");
		Count(s);
		Extract(s);
	}
	else if(flag == 0)
	{
		printf("Input Error!\n");
	}
	else
	{
		printf("Error!\n");
	}
	system("pause");
	return 0;
}

总结

        在编写过程中由于好久不写C语言,同时不允许调包,走了一些弯路,好在最后算是实现了题目要求。感觉是有一些收获的,对C语言字符串相关操作有了进一步认识。

        同时总结了一些C语言字符串相关函数,在我发的另一篇文章,链接附在后面,有兴趣的小伙伴可以看一眼。

        C语言字符串常用函数总结(持续更新)_文刀宝宝的博客-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值