输入一个字符串,内有数字和非数字字符,如:ak123x456 17960?302gef4563,将其中连续的数字作为一个整体,依次存放到一数组a中,例如123放入a[0],456放入a[[1]],… … 。编程统计共有多少个整数,并输出这些数。
*我是在数据结构串那一章的习题里面遇到的此题,所以觉得应该用串相关的知识和形式解决,我在网上看过几篇解决此题的方法,但是都没有涉及串的知识。心血来潮,在下面我写了自己理解的代码,可能有多余的地方,希望大家指正,提提建议。 *
#include "stdio.h"
#include "stdlib.h"
typedef struct hstring
{
char *ch;//指针域
int length;//长度计数
}String;
bool strAssign(String &s,char *c)//给字符串赋值
{
if(s.ch)//如果不是空字符串,则将其置空,即清空原字符串
s.ch = NULL;
int i = 0;
while(c[i])//遍历字符数组,得到长度
{
i++;
}
s.length = i;
if(i>0)如果长度大于0,说明字符串不为空
{
if(!(s.ch =(char*)malloc(i*sizeof(char)))) //分配一个String空间
return false; //分配失败,则返回false
for(int j=0;j<i;j++) //否则分配成功,给字符串赋值
s.ch[j] = c[j];
}
return true; //一切正常的话,最后返回成功
}
bool strAssign_S(String &s,String str)//两个String字符串互相赋值
{
if(s.ch)//如果不是空字符串,则将其置空,即清空原字符串
s.ch = NULL;
s.length = str.length;//把目标Sring str的长度赋值给要操作的String s
if(str.length>0)//如果大于0,说明目标String str不为空串
{
if(!(s.ch =(char*)malloc(str.length*sizeof(char))))//如果申请空间不成功,返回false
return false;
for(int j=0;j<str.length;j++)//遍历目标Sring str赋值给要操作的String s
s.ch[j] = str.ch[j];
}
return true;//一切正常的话,最终返回true
}
bool strSub(String &sub,String s,int pos,int len)//剪切字符串
{
if(pos<0||pos>s.length - 1||len<0||len>s.length-pos)//剪切位置不合理,返回false
return false;
if(sub.ch)//如果不是空字符串,则将其置空,即清空原字符串
sub.ch = NULL;
if(len==0)//如果所要剪切的长度为0,那么sub字符串就是空串
{
sub.ch = NULL;
sub.length = 0;
}
else//正常情况
{
sub.ch = (char *)malloc(sizeof(char)*len);//申请长度为len的String串空间
for(int i= 0;i<len;i++)遍历,将要剪切的字符串赋值给新字符串sub
{
sub.ch[i] = s.ch[pos+i];
}
sub.length = len;
}
return true;//一切正常的话,返回true
}
int str_num(String s)//一次剪切一个数,返回第一组数字字符串结束时的长度
{
int i = 0,flag=0;//i用来标记s的位置,同时统计第一组数字的长度,flag用来标记连续的数字串
while(i<s.length)
{
if('0'<=s.ch[i]&&s.ch[i]<='9')//字符串是数字,继续遍历
{
flag++;
}
else
{
if(flag>0)//字符串不是数字,停止遍历
break;
}
i++;
}
return i;
}
void show(String &s)//显示String字符串
{
int i=0;
while(i<s.length)
{
printf("%c",s.ch[i]);
i++;
}
printf("\n");
}
String get_firstnumstr(String s)//返回首个数字字符串
{
int i = 0,k = 0,flag=0,pos=0;
String r;//用来保存首个数字字符串
while(i<s.length)//遍历
{
if('0'<=s.ch[i]&&s.ch[i]<='9')//连续的数字遍历
{
if(flag==0)//用pos记录剪切的起始位置
pos = i;
flag++;//用flag记录剪切的长度
}
else //出现非数字字符
{
if(flag>0)/同时flag已经大于零,说明出现非数字字符之前有数字了
break;
}
i++;
}
strSub(r,s,pos,flag);//将首个数字字符串剪切下来,使得原字符串缩短
return r;
}
int strlen(String s)//返回String字符串长度
{
return s.length;
}
int main()
{
char str[80] = "ak123x456 17960?302gef4563";
String a[20];//把数字字符串保存在a数组
String b[20];//用于保存剪切后的字符串
String strs; //原字符串
int i =0;
bool sub_flag=true;//是否还能剪切标志位
strAssign(strs,str);//赋初值
printf("原字符串是:");
show(strs);
strSub(b[0],strs,0,strlen(strs));//把完整的字符串先给b[0]保存
while(sub_flag)
{
strAssign_S(a[i],get_firstnumstr(b[i]));//把第一个数字字符串给数组a保存
i++;
sub_flag=strSub(b[i],b[i-1],(int)str_num(b[i-1]),(int)(strlen(b[i-1])-str_num(b[i-1])));
}
printf("该字符串有%d个数字,分别如下:\n",i);
for(int k=0;k<i;k++)
show(a[k]);
return 0;
}
运行结果如下:上述程序的执行结果如下,你可以任意改变原字符串,经过测试,均符合要求。