大魔王程序员生成记#06.2#C语言习题
目录
13.第一个只出现一次的字符 "abacbd"
14."abcdef"==>cdefab 左旋数组
15.输出杨辉三角,10行
16.输出1-n^2的自然数构成的魔方阵
17.函数的返回值,是如何带出函数的?寄存器有关?
18.汉诺塔问题
19.在第一个字符串中,删除第二个字符串中的所有字符串中所有的字符
"welcome tulun" "come" ==》"wltulun"
20.定义一个结构体变量(包括年,月,日)。计算该日在本年中是第几天,注意闰年问题
21.筛选法求100以内的所有素数
22.字符串相加Hello world! 102
23.括号匹配.({()}) “({)” 或者 “([{})]” 都不符合要求
24.求一个有序数组中两个值相加为k的数字,返回这两个数字的下标。
25.数组中前K个最小的数字
26.出现次数超过数组长度一半的数字,如:{1,2,3,2,2,2,5,4,2}
27.左数第 bit 位 置 1
28.左数第 bit 位置 0
29.获取第 bit 位的值
30.写一个函数,它从一个字符串中提取一个子字符串,返回值是存储在dst数组中的子字符串的长度
31.从一个字符串中除去多于的空格
32.长度受限的字符串拷贝
33.长度受限的字符串连接函数
34.长度受限的字符串比较
35.查找字符ch,在给定字符串出现的最后一次
36.字符串查找给定字符,第n次出现的位置
37.strlen()函数实现
38.strchr()函数实现
39.strstr()函数实现
40.单位矩阵3阶
41.将字符串中的空格替换为#25
42.将字符串中的字符'*'移到字符串的前面 如:"tu**lu**n**ba**by",处理后为:"********tulunbaby
43.可变参数编程,求和.int sum(int count,..)
44.可变参数编程,多种输出.void Print(const char *str,...)
45.非常规方法比较两个数的大小
46.写一个函数返回bool值,来判断给定的字符串A和B(假设都是小写字母),是否是B中的字符都存在于A中,如果是返回true,否则返回false
47.LeetCode06:将一个给定的字符串根据给定的行数以从上往下,从左到右进行Z字形排列。
48.LeetCode30:与所有单词相关联的字串
13.第一个只出现一次的字符 "abacbd"
char FirstNotRepeate(char *str )
{char *pbegin=str;char *pend=str;int len=strlen(str);//计算字符串长度while(len!=0)//每个字符进行一次遍历{while(*pend!='\0'){if(pbegin==pend)//指向相同地址就略过,即两个指针指向同一个数时,pend就略过这个数{pend++;}if(*pbegin==*pend)//两个数字相同时,记录出现一次的指针向后移{pbegin++;}pend++;}pend=str;//重置len--;}return *pbegin;
}
int main()
{char str[]="abacbd";printf("%c\n",FirstNotRepeate(str));return 0;
}
14."abcdef"==>cdefab 左旋数组
char* Left_Arry(char *str,int num)
{assert(str!=NULL);char *p=str;int len=strlen(str);//计算字符串的长度int t=len-num;char str2[10]={};//创建一个用来保存需要移动的字符for(int i=0;i<num;i++){str2[i]=str[i];//将需要左移的字符提出}for(int j=0,i=num;j<=len-num;j++,i++){str[j]=str[i];//将原数组左移}for(int i=0;i<num;i++,t++){str[t]=str2[i];//将提出的字符补到移动后的数组}return str;
}
int main()
{char str[]="abcdef";printf("%s\n",Left_Arry(str,2));return 0;
}
解题思路:将需要转移的字符提出,将原数组前移,将转移出的字符补在原数组中。
15.输出杨辉三角,10行
void Job(int (*arr)[10],int row,int col)
{for(int i=0;i<row;i++){for(int j=0;j<col;j++){if(j==0||i==j){arr[i][j]=1;//将每行的第一个和最后一个元素都赋值为1}else{arr[i][j]=arr[i-1][j]+arr[i-1][j-1];//第n+1行的第i个数==第n行的 第i-1个数+第i个数}}}
}void Show(int (*arr)[10],int row,int col)
{for(int i=0;i<row;i++){for(int j=0;j<=i;j++){printf("%d ",arr[i][j]);}printf("\n");}
}
int main()
{int arr[10][10];Job(arr,10,10);Show(arr,10,10);return 0;
}
16.输出1-n^2的自然数构成的魔方阵
/*
魔方阵满足的计算方法:
1.每一个数存放的位置是前一个数的行数减一,列数加一
2.上一个数行数为一,则下一个数行数为n
3.上一个数列数为n,则下一个数行数减一
4.位置有数或上一个数是第一行第n列,下一个数放在上一个数的下面
*/
void Job1(int (*arr)[3],int n)
{int row=n;int col=n;assert(n%2!=0);//n只能为奇数for(int i=0;i<row;i++){for(int j=0;j<col;j++){arr[i][j]=0;}}col=n/2;//初始化,数字1的坐标row=0;arr[0][col]=1;for(int k=2;k<=n*n;k++){row=row-1;col=col+1;if(row<0&&col>n-1)//判断是否为第一行第n列{row=row+2;col=col-1;}if(row<0)//若为真,说明前一个数行数为1{row=n-1;}if(col>n-1)//若为真,说明前一个数列数为n{col=0;}if(arr[row][col]==0)//若为真,说明位置上无数{arr[row][col]=k;}else //位置上有数,变为前一个数的下一行{row=row+2;col=col-1;arr[row][col]=k;}}
}
17.函数的返回值,是如何带出函数的?寄存器有关?
答:
<= 4字节 通过寄存器带出来
>4 <=8 字节 通过两个寄存器带出来
>8 字节 通过产生临时量,此时返回值太大,寄存器已经没有足够的内存存放它
临时量是什么时候产生的?临时量是怎么找到的?怎么给临时量赋值的?
答:在函数调用之前;在调用函数之前,将临时量地址入栈,最后通过将被调用函数的返回值拷贝给临时量,将函数返回值带出。
参数带默认值的函数:
如:int sum(int a,int b,int c = 10);
给默认值从右边的参数给,参数的默认值只能给一次。
18.汉诺塔问题
void Hanno(int n,char pos1,char pos2,char pos3)
{if(n==1){printf("%c-->%c\n",pos1,pos3);//只有一个盘子时,只需要将A-->C}else{Hanno(n-1,pos1,pos3,pos2); //A 借助C-->Bprintf("%c-->%c\n",pos1,pos3); //A-->BHanno(n-1,pos2,pos1,pos3); //B 借助A-->C}
}
int main()
{Hanno(3,'A','B','C');return 0;
}
19.在第一个字符串中,删除第二个字符串中的所有字符串中所有的字符
"welcome tulun" "come" ==》"wltulun"
char *Deletechars(char *st1,char *st2)
{assert(st1!=null||st2!=null);char *pb=st1;while(*st2!='\0'){while(*pb!='\0'){if(*st2==*pb) //如果两个字母相同赋值为0{*pb='0';}pb++;}st2++;pb=st1;//重新初始化}return pb;
}
void show(char* st1)
{assert(st1!=0);while(*st1!='\0'){while(*st1=='0')//如果有为0的元素,略过{st1++;}printf("%c",*st1);st1++;}printf("\n");
}
int main()
{char st1[]="welcome tulun";char st2[]="come";DeleteChars(st1,st2);Show(st1);return 0;
}
20.定义一个结构体变量(包括年,月,日)。计算该日在本年中是第几天,注意闰年问题
struct Days
{int year;int month;int day;
};
void Job1(Days day)
{int sum=0;switch(day.month){case 1:sum=day.day;break;case 2:sum=day.day+31;break;case 3:sum=day.day+59;break;case 4:sum=day.day+90;break;case 5:sum=day.day+120;break;case 6:sum=day.day+151;break;case 7:sum=day.day+181;break;case 8:sum=day.day+212;break;case 9:sum=day.day+243;break;case 10:sum=day.day+273;break;case 11:sum=day.day+304;break;case 12:sum=day.day+334;break;}if((day.year%4==0&&day.year%100!=0)||day.year%400==0)//闰年的判断方法,能被4整除不能被100整除;能被400整除{sum++;}printf("%d月%d日是%d年的第%d天\n",day.month,day.day,day.year,sum);
}
int main()
{Days d={2018,11,3};Job1(d);return 0;
}
21.筛选法求100以内的所有素数
void Job1()
{int arr[101]={0};for(int i=0;i<100;i++){arr[i]=i+1;}for(int j=3;j<100;j++)//从第三个元素,即4开始{for(int i=2;i<j;i++){if(arr[j]%i==0)//素数赋值为0{arr[j]=0;}}}printf("100以内的素数有:\n");for(int i=0;i<100;i++){if(arr[i]==0)//元素为0的跳过{continue;}printf("%d,",arr[i]);}printf("\n");
}
int main()
{Job1();return 0;
}
1.如何打印"Blunder??!??"
答:printf("\"Blunder??!??\"");
2.\40的值是多少?\100,\x40,\x100,\0123,\x0123
答:\40: ;\100:@;\x40:@;\x100:"256"对字符来说太大;\0123:换行3;\x0123:"291"对字符来说太大
22.字符串相加Hello world! 102
void Job1()
{char arr[40];signed char checksum=-1;int i=0;printf("输入字符串:");gets(arr);while(arr[i]!='\0'){checksum+=arr[i];i++;}checksum+='\n';//回车printf("输出结果:%s %d\n",arr,checksum);
}
int main()
{Job1();return 0;
}
23.括号匹配.({()}) “({)” 或者 “([{})]” 都不符合要求
int Job2(char *arr)
{int j=0;int i=0;char temp1[40];while(arr[i]!='\0'){if(arr[i]=='('||arr[i]=='{'||arr[i]=='[')//只要是左括号就写入{temp1[j]=arr[i];j++;i++;continue;}//第一次出现右括号,与他相邻的必然是他的左括号if(arr[i]==')'){j--;if(temp1[j]=='('){i++;}else{return -1;}}if(arr[i]=='}'){j--;if(temp1[j]=='{'){i++;}else{return -1;}}if(arr[i]==']'){j--;if(temp1[j]=='['){i++;}else{return -1;}}}return 1;
}
int main()
{char arr[]="{([()])()";if(Job2(arr)==1){printf("ok\n");}else{printf("no\n");}return 0;
}
24.求一个有序数组中两个值相加为k的数字,返回这两个数字的下标。
void Job3(int *arr,int len,int key)
{int bgn=0;int end=len-1;for(int i=0;i<len;i++)//有序数组(前提是1开头),相加为k,则k==第一个元素+k的前一个元素{if(arr[i]==key){end=i-1;break;}}printf("这两个数字的下标为:\n");while(arr[bgn]+arr[end]==key&&bgn<=end){printf("%d %d\n",bgn,end);bgn++;end--;}
}
int main()
{int arr[]={1,2,3,4,5,6,7,8,9};int len=sizeof(arr)/sizeof(arr[0]);int key=8;printf("key为:%d\n",key);Job3(arr,len,key);return 0;
}
25.数组中前K个最小的数字
int Job(int *arr,int low,int high)
{int tmp ;while(low < high){while(arr[low] > arr[high] && low < high){low++;}while(arr[low] < arr[high] && low < high){high--;}}tmp = arr[low];return tmp;
}
int main()
{int arr[] = {14,5,9,21,11,3,7,19};int start = 0;int end = 6;//前k个int k = Job(arr,start,end-1);printf("数组中前%d个最小的数字为:%d\n",end,k);return 0;
}
26.出现次数超过数组长度一半的数字,如:{1,2,3,2,2,2,5,4,2}
/*
方法一:
思路:一个数字出现的次数超过数组的一半长度,根据一次划分函数,在数组的中位数上一定是这个数。
*/
/*
方法一:
思路:一个数字出现的次数超过数组的一半长度,根据一次划分函数,在数组的中位数上一定是这个数。
*/
void Swap(int *arr,int low,int high)
{int tmp = arr[low];arr[low] = arr[high];arr[high] = tmp;
}
int Job1(int *arr,int low,int high,int len)
{srand((unsigned int)time(NULL));Swap(arr,low,rand()%(high-low)+low);//随机生成 基准int tmp = arr[low];while(low < high){while(low < high && arr[high] >= tmp){high--;}if(high < low){break;}else{arr[low] =arr[high];}while(low < high && arr[low] <= tmp){low++;}if(low > high ){break;}else{arr[high] = arr[low];}}arr[low] = tmp;return arr[(len)/2];
}
int main()
{int arr[] = {1,2,3,2,2,2,5,4,2};int len = sizeof(arr)/sizeof(arr[0]);int key = Job1(arr,0,len-1,len);//方法一printf("%d\n",key);return 0;
}
/*
方法二:(一个多于一半数组的数,出现次数比其他数的总和还要多)
思路:在遍历数组的过程中,保存两个值,一个是数组中数字,一个是出现次数。
当遍历到下一个数字时,如果这个数字跟之前保存的数字相同,则次数加1,如果不同,则次数减1。
如果次数为0,则保存下一个数字并把次数设置为1。
*/
/*
方法二:(一个多于一半数组的数,出现次数比其他数的总和还要多)
思路:在遍历数组的过程中,保存两个值,一个是数组中数字,一个是出现次数。
当遍历到下一个数字时,如果这个数字跟之前保存的数字相同,则次数加1,如果不同,则次数减1。
如果次数为0,则保存下一个数字并把次数设置为1。
*/int Job3(int *arr,int len)
{int sum = 0;int top = 1;int *brr = (int *)malloc(sizeof(int)*2);brr[top] = arr[0];//brr的初始化brr[sum] = 1;for(int i =1;i < len;i++){if(brr[top] != arr[i]){brr[sum]--;}else{brr[sum]++;}if(brr[sum] == 0){brr[top] = arr[i];brr[sum] = 1;}}return brr[top];
}
int main()
{int arr[] = {1,2,3,2,2,2,5,4,2};int len = sizeof(arr)/sizeof(arr[0]);int key = Job3(arr,len);//方法二printf("%d\n",key);return 0;
}
27.左数第 bit 位 置 1
void Job(int num,int bit)
{int n= pow((double)2,(32-bit)); // num | 2^(32-k)num = num | n;printf("%d\n",num);
}
int main()
{Job(5,31);return 0;
}
28.左数第 bit 位置 0
void Job1(int num,int bit)
{int n= pow((double)2,(32-bit));// num ^ 2(32-k)num = num ^ n;printf("%d\n",num);
}
int main()
{Job1(5,30);return 0;
}
29.获取第 bit 位的值
void Job2(int num,int bit)
{num = num >>bit-1;//左移 (32 - bit) | 1printf("%d\n",(num ^ 1 ? 0:1));
}
int main()
{Job2(5,3);return 0;
}
30.写一个函数,它从一个字符串中提取一个子字符串,返回值是存储在dst数组中的子字符串的长度
int SubStr(char *dst,char *src,int start,int len)
{int count = 0;int j ;int i ;assert(*src != NULL);for( i= start,j = 0; i < len ;i++,j++){dst[j] = src[i];count++;}dst[j] = '\0';return count;
}
int main()
{char arr[] = "abcdef";char brr[20] ;int len = sizeof(arr)/sizeof(arr[0]);int start = 2;int len1 = SubStr(brr,arr,start-1,len);printf("%d %s\n",len1,brr);return 0;
}
31.从一个字符串中除去多于的空格
void Deblank(char *string)
{assert(*string != NULL);char *pb = string;char *pe = string;while(*pe != '\0'){if(*pe == ' ' && *pe++ == ' ')//遇到空格判断后面是否还有空格,有pb走一步,准备覆盖 (pe++)可以修改成pe+1{pb++;}while(!isalpha(*pe))//过滤多于空格{pe++;}*pb = *pe;//覆盖pe++;pb++;}*pb = '\0';
}
int main()
{char arr[] = "abc bcd def dg";Deblank(arr);printf("%s\n",arr);return 0;
}
另一种方法:考虑前后都有空格
void Deblank(char *string)
{assert(*string != NULL);char *pb = string;char *pe = string;while(!(isalpha(*pe))){pe++;pb++;}while(*pe != '\0'){if(*pe == ' ' && *(pe+1) == ' ')//遇到空格判断后面是否还有空格,有pb走一步,准备覆盖{pb++;}while(!isalpha(*pe) )//过滤多于空格{if(*pe == '\0')//末尾有空格{*(pb-1) = '\0';return ;}pe++;}*pb = *pe;//覆盖pe++;pb++;}*pb = '\0';
}int main()
{char arr[] = " abc bcd def dg ";Deblank(arr);printf("%s\n",arr);return 0;
}
32.长度受限的字符串拷贝
char *My_strcnpy(char *des,const char *src,int n )
{assert(des!=NULL&&src!=NULL);assert(n>0&&n<strlen(src));int i ;for(i = 0;i < n && src[i] != '\0';i++){des[i] = src[i];}des[i] = '\0';return des;
}
33.长度受限的字符串连接函数
char *My_strncat(char *des,const char *src,int n )
{assert(des!=NULL&&src!=NULL);assert(n>0&&n<strlen(src));char *pb = des;while(*pb != '\0'){pb++;}while(*src != '\0'){*pb = *src;pb++;src++;}*pb = '\0';return pb;
}
34.长度受限的字符串比较
int My_strcnmpy(const char *str1,const char *str2,int n)
{assert(str1 != NULL && str2 != NULL);assert(n>0&&n<strlen(str1)&&n<strlen(str2));const char *p1 = str1;const char *p2 = str2;while(*p1 != '\0' || *p2 != '\0'){if(*p1 == *p2){p1++;p2++;}else{if(*p1 > *p2){return 1;}else{return -1;}}}
}
35.查找字符ch,在给定字符串出现的最后一次
int My_strrchr(const char *str,char ch)
{assert(str != NULL);for(int i = strlen(str)-1;i >= 0;i--){if(str[i] == ch){return i;}}
}
36.字符串查找给定字符,第n次出现的位置
int My_strnchr(const char *str,char ch,int n)
{assert(str != NULL);int count = 0;for(int i = 0;i < strlen(str);i++){if(str[i] == ch){count++;if(count == n){return i;}}}
}
37.strlen()函数实现
int My_strlen(const char *str)
{assert(str != NULL);int len = 0;while(*str != '\0'){len++;str++;}return len;
}
38.strchr()函数实现
int My_strchr(const char* str,char ch)
{assert(str != NULL);int count = 0;while(*str != '\0'){if(*str == ch){return count;}count++;str++;}
}
39.strstr()函数实现
int My_strstr(char *str1, char *str2)
{assert(str1 != NULL && str2 != NULL);char *pb = str1;char *pe = str2;int i = 0;int j = 0;while(i < strlen(str1) && j < strlen(str2)){if(pb[i] == pe[j]){i++;j++;}else{i = i-j+1;j = 0;}}if(j == strlen(str2)){return i-strlen(str2);}
}
int main()
{char arr[] = "abcdefghijklmnopqrst";char brr[] = "hij";printf("%d\n",My_strlen(arr));char d = 'd';printf("%d\n",My_strstr(arr,brr));return 0;
}
40.单位矩阵3阶
void Identity_matrix(int (*p)[3] ,int row,int col)
{for(int i =0;i < row;i++){for(int j =0;j < col;j++){if(i == j){p[i][j] = 1;}else{p[i][j] = 0;}}}for(int i = 0;i < row; i++){for(int j = 0;j < col;j++){printf("%d ",p[i][j]);}printf("\n");}
}
int main()
{int p[3][3];Identity_matrix(p,3,3);return 0;
}
单位矩阵1阶
void Identity_matrix(int *p ,int row,int col)
{assert(p != NULL);p[0] = 1;printf("%d\n",p[0]);
}
int main()
{int q[1][1];Identity_matrix(p,1,1);return 0;
}
41.将字符串中的空格替换为#25
int Job(char *arr)
{assert(arr != NULL);int count = 0;while(*arr != '\0'){if(*arr == ' '){count++;}arr++;}return count;
}
char* Job1(char *arr,int len,char *brr)
{assert(arr != NULL);while(*arr != '\0'){if(*arr == ' '){*brr = '#';brr++;*brr = '2';brr++;*brr = '5';brr++;arr++;}else{*brr = *arr;brr++;arr++;}}*brr = '\0';return brr;
}
int main()
{char arr[] = "i am tulun";int len = sizeof(arr)/sizeof(arr[0]);char *brr = (char *)malloc(sizeof(char)*(len + Job(arr)*3));Job1(arr,len,brr);printf("%s\n",brr);return 0;
}
42.将字符串中的字符'*'移到字符串的前面 如:"tu**lu**n**ba**by",处理后为:"********tulunbaby
char* Job2(char * arr,char *brr,int len)
{assert(arr != NULL);int j = 0;for(int i = 0;i < len;i++){if(arr[i] == '*'){brr[j] = arr[i];j++;}else{continue;}}for(int i = 0;i < len ;i++){if(isalpha(arr[i])){brr[j] = arr[i];j++;}}brr[j] = '\0';return brr;
}
int main()
{char arr[] = "tu**lu**n**ba**by";int len = sizeof(arr)/sizeof(arr[0]);char *brr = (char *)malloc(sizeof(char)*len);Job2(arr,brr,len);printf("%s\n",brr);return 0;
}
/*
(1) va_list: 定义一个va_list型的变量ap,也就是char *;
(2) va_start:获取到可变参数表的首地址,并将该地址赋给指针ap;
(3) va_arg: 获取当前ap所指向的可变参数,并将指针ap指向下一个可变参数。注意,该宏的第二个参数为类型;
(4) va_end: 结束可变参数的获取。
*/
43.可变参数编程,求和.int sum(int count,..)
int Sum(int count,...)
{char *p =NULL;p = (char *)(&(count))+sizeof(count);int sum = 0;for(int i = 0;i < count;i++){sum += *(int *)((p += sizeof(int))-sizeof(int));}p = NULL;return sum;
}
int main()
{printf("%d\n",Sum(2,10,20));return 0;
}
44.可变参数编程,多种输出.void Print(const char *str,...)
同一类型
void Print(int count,...)//10,20
{char *p =NULL;p = (char *)(&(count))+sizeof(count);int tmp = 0;for(int i = 0;i < count;i++){tmp = *(int *)((p += sizeof(int))-sizeof(int));printf("%d\n",tmp);}p = NULL;
}
不同类型
void Print(const char *str,...)
{char* list = NULL;list = (char*)(&str) + sizeof(str);int num;int ch;char *p;double d;while(*str != '\0'){if(*str == '%'){switch(*(str+1)){case 'd':num = ( *(int *)((list += sizeof(int)) - sizeof(int)) );printf("%d",num);str += 2;break;case 'c':ch = ( *(char *)((list += sizeof(char)) - sizeof(char)) );putchar(ch);str += 2;(char *)list += 3;break;case 's':p = ( *(char **)((list += sizeof(char*)) - sizeof(char*)) );printf("%s",p);str += 2;break;case 'f':d =( *(double *)((list += sizeof(double)) - sizeof(double)));printf("%f",d);str += 2;break;default:putchar(*str++);break;}}else{putchar(*str++);}}list = NULL;
}
int main()
{Print("%%,%s,%d,%c,%f\n","hello",10,'a',12.5);return 0;
}
45.非常规方法比较两个数的大小
int Max(int a,int b)
{return (a - b) >>31 ? -1: (a-b ? 1 : 0);
}
int main()
{printf("%d\n",Max(20,30));return 0;
}
46.写一个函数返回bool值,来判断给定的字符串A和B(假设都是小写字母),是否是B中的字符都存在于A中,如果是返回true,否则返回false
bool CheckString(const char *A,const char *B)
{bool crr[127] = {false};//bool crr[127] = {true};只有第一个是true,后面的是false。如果初始化为false,后面的都是falsewhile(*A != '\0'){crr[*A] = true;A++;}while(*B != '\0'){if(!crr[*B]){return false;}B++;}return true;}int main()
{char arr[] = "abcde";char brr[] = "bcd";printf("%d\n",CheckString(arr,brr));return 0;}
47.LeetCode06:将一个给定的字符串根据给定的行数以从上往下,从左到右进行Z字形排列。
方法一 + 方法二
/*
方法一:动态开辟二维数组
*/
void Job(char *arr,int row)// row行 col列
{assert(arr != NULL);if(row == 1){printf("%s\n",arr);return ;}int col = strlen(arr)/(2*row-2)*(row-1);//求得列数int len = strlen(arr) ;char **brr;brr = (char **)calloc(row,sizeof(char *));//先行后列 先有楼层,才有楼牌号for(int i = 0;i < row;i++){brr[i] = (char *)calloc(col,sizeof(char));}int i = 0;int j =0;int r =0;//记录列数int k =0;//记录arr的长度while(k < len){i = 0;r = 0;while(r <row && k < len)//放完整一列{brr[i][j] = arr[k];k++;i++;r++;}j++;//进入下一列i = row-2;//下一列初始化for(int z = row-2;z > 0;z--,i--,k++,j++)//放不完整一列 放(row-2)次{if(k < len){brr[i][j] = arr[k];}}}for(i = 0;i < row;i++){for(j = 0;j < col;j++){printf("%c",brr[i][j]);}printf("\n");}for(i = 0;i < row;i++)//释放,先释放一维{brr[i];}free(brr);//再释放二维
}
//方法二:根据数学关系进行变换
char* Convert(char* s, int numRows)
{assert(s != NULL);if(numRows == 1){return s;}int len = strlen(s)+1;char *arr = (char*)malloc(sizeof(char)*len);int cycLen = 2 * numRows-2;int k = 0;for(int i = 0;i < numRows; i++){for(int j = i; j < len-1;j += cycLen){arr[k++] = s[j]; if (i != 0 && i != numRows - 1 && j + cycLen - 2*i < len-1){arr[k++]= s[j + cycLen - 2*i];}}}arr[k] = '\0';return arr;
}int main()
{char arr[] = "LEETCODEISHIRING";//方法一//测试一int row = 3;Job(arr,row);//测试二int row1 = 4;Job(arr,row1);//测试三int row2 = 1;Job(arr,row2);char s[] ="LEETCODEISHIRING";//方法二//测试一char *brr = NULL;int numRows = 3;brr = Convert(s,numRows);printf("%s\n",brr);free(brr);//测试二char *brr1 = NULL;int numRows1 = 4;brr = Convert(s,numRows1);printf("%s\n",brr);free(brr1);//测试三char *brr2 = NULL;int numRows2 = 1;brr = Convert(s,numRows2);printf("%s\n",brr);free(brr2);return 0;
}
48.LeetCode30:与所有单词相关联的字串
给定一个字符串S和一些长度相同的单词words,在S中恰好可以找出串联words中所有单词的子串的起始位置。
子串要与words中的单词完全匹配,中间不能有其他字符,但不需要考虑words中单词串联的顺序。
如:S ="barfoothefoobarman",
words = {"foo","bar"}
输出:[0,9]
解释从索引0和9开始的子串分别是"barfoo"和"foobar"
输出的顺序不重要,[9,0]也是有效答案
方法一 + 方法二
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 4
//方法一:使用两个哈希表进行比对;一个存单词和出现次数;另一个在遍历字符串时记录出现次数是否和第I个//一样;一样则找到;不一样则继续遍历
int* FindSubstring(char* s, char (*words)[4],int many, int len, int* brr)
{assert(s != NULL && words != NULL && brr != NULL);unsigned char arr[255] = {0}; int len1 = strlen(s);int k = 0;for(int i = 0;i < many;i++){for(int j = 0;j < len;j++){arr[words[i][j]]++;}}for(int i = 0;i < len1-many*len;i++){unsigned char tmp[255] = {0};int j ;for(j = i; j < i+many*len;j++){if(arr[s[j]]){tmp[s[j]]++;if(arr[s[j]] < tmp[s[j]]){break;}}else{break;}}j = j-i;if(j == many*len){brr[k] = i;k++;//i = i+many*len;}}return brr;
}//方法二:计算每个单词出现的位置,每个单词出现的位置+字长是否等于下一个单词出现的位置
int* FindSubstring(char* s, char (*words)[SIZE], int many,int size, int* returnSize)
{assert(s != NULL && words != NULL );int len = strlen(s);int k = 0;int l = 0;int tmmp[20] = {0};for(int i = 0; i < many; i++){char tmp[SIZE];for(int j = 0 ; j < len ; j++){tmp[0] = s[j++];tmp[1] = s[j++];tmp[2] = s[j++];tmp[3] = '\0';if(!strcmp(tmp,words[i])){tmmp[k++] = j-3;j +=2;}j -= 3;}}int *arr = (int *)malloc(sizeof(int)*k);for (int i = 0; i < k;i++){for(int j = 0 ; j < k ;j++){if(i == j){continue;}if((tmmp[i] +size) == tmmp[j] ){arr[l++] = tmmp[i];}}}*returnSize = l;return arr;
}
int main()
{//测试一char arr[][4]={"foo","bar"};//方法一char s[] = "barfoothefoobarman";int *drr = (int *)calloc(2,sizeof(int));drr = FindSubstring(s,arr,2,3,drr);for(int i =0;i<2;i++){if(drr[i] == 0 && i != 0){continue;}printf("%d\n",drr[i]);}//测试二char arr1[][4]={"ood","stu"};char s1[] = "goodgoodstudydaydayup";int *drr1 = (int *)calloc(2,sizeof(int));drr1 = FindSubstring(s1,arr1,2,3,drr1);for(int i =0;i<2;i++){if(drr1[i] == 0 && i != 0){continue;}printf("%d\n",drr1[i]);}//测试三char arr2[][4]={"foo","bar"};char s2[] = "bofarothefoobarman";int *drr2 = (int *)calloc(2,sizeof(int));drr2 = FindSubstring(s2,arr2,2,3,drr2);for(int i =0;i<2;i++){if(drr2[i] == 0 && i != 0){continue;}printf("%d\n",drr2[i]);}//char s[] = "barfoothefoobarman";//方法二//char words[][SIZE] = {"foo","bar"};//int *arr = NULL;//int returnSize ;//arr = FindSubstring(s,words,2,3,&returnSize);//for(int i = 0; i < returnSize; i++)//{// printf("%d\n",arr[i]);//}//free(arr);return 0;
}
大魔王程序员生成记#06.2#C语言习题相关推荐
- 大魔王程序员生成记#06.1#C语言习题
目录 1.求斐波那契数列前40项 2.求连续子数组的最大和 3.辗转相处,求最大公约数 4.判断大小端 5.大小端的转换 6.int类型 指针 float 和零值如何比较 7.对指针的理解 8.c ...
- c语言生成一串变量,大魔王程序员生成记#02#C语言基础——变量与常量
变量: 变量代表一个具有名字的,具有特定属性的一个存储单元.它用来存放数据,也就是存放变量的值.在程序的运行期间,变量的值是可以改变的. 变量的作用范围:在花括号之间. int main() { in ...
- 大魔王程序员生成记#01#C语言基础
预处理指令.#include<stdio.h>(或者#define).C编译系统在对源程序编译之前,先由一个预编译器进行处理,将stdioo.h头文件的内容读出来,放在#include指令 ...
- python是通用编程语言吗-2020年,编程语言将不再只属于程序员,尤其是这门语言...
原标题:2020年,编程语言将不再只属于程序员,尤其是这门语言 "学python,那不就是去做程序员吗?" 一提到python,许多同学第一反应会觉得,这是要去做程序员才需要学的技 ...
- 黑马程序员:Java基础总结----Java语言编程规范
黑马程序员:Java基础总结 Java语言编程规范:参考自SUN公司文档 ASP.Net+Android+IO开发..Net培训.期待与您交流! I. 排版规范 A. 规 ...
- 初级程序员软考重点5 程序设计语言
初级程序员软考重点5 程序设计语言 一.程序设计语言及其构成 1. 常见的高级程序语言 2. 通用的程序设计语言 3. 标记语言 二.表达式 1. 表达式的类型及转换规则 示例: 1. a入栈 2. ...
- 程序员之路──如何学习C语言并精通C语言
程序员之路──如何学习C语言 学习C语言不是一朝一夕的事情,但也不需要花费十年时间才能精通.如何以最小的代价学习并精通C语言是本文的主题.请注意,即使是"最小的代价",也绝不是什么 ...
- 菜鸟程序员成长史 --记 Github 1000+ contributions
其实一直以来想写一篇文章总结这几年的技术学习,刚好趁着自己的第一次github contribution 达到1000+,写篇文章总结以下.本文篇幅较长,我会分为几个章节来分别阐述. 博客篇 为什么我 ...
- 《程序员养成记》第8集 数据结构才是程序的灵魂
如果生活说生活是由各种规则构造,那么在规则之下还觉得生活有趣的无法就是每个有趣的灵魂,编程亦是如此! #include <stdio.h>int main() {char you_qu = ...
最新文章
- 学习进度条(第一周)
- PXE新手经典思路引导
- web前端知识点太多_web前端入门必学的16个知识点,都来看一下吧
- openerp学习笔记 domain 的应用
- Java并发编程—Atomic原子类
- 在ASP.NET Core中实现一个Token base的身份认证
- js--------1.时间
- 数据库事务的隔离机制
- SparkSQL-从0到1认识Catalyst
- (纪录片)电的故事 Shock Awe The Story of Electricity
- ZendFramework多模块配置
- SQL Server 各版本密钥
- 解决qt下VCI_OpenDevice一直返回0的问题
- win10卸载软件_一款适合于windows端的卸载神器 彻底清理残留软件
- python画红色填充三角形_用单独的颜色填充Matplotlib三元组中的三角形
- 【资源下载】敬勇 - 一条执行时间小于1秒的 SQL 引发的性能问题
- Apache的Order Allow,Deny 规则
- CentOS 7.5 搭建以太坊私联(联盟链)及区块链浏览器
- Python数据挖掘-NLTK文本分析+jieba中文文本挖掘
- 电脑公司特别版8.5出现 fastfat.sys文件不正确及蓝屏错误的原因之一