K&;R练习2-5,误差控制可能达到非无效函数c的末尾
编写函数any(s1,s2),它返回字符串s1中的第一个位置,其中出现了字符串s2中的任何字符;如果s1不包含s2中的任何字符,则返回-1。 当我编译我的代码时,我得到“控件可能会到达非void函数的末尾。导致错误的部分,下面是我的代码:K&;R练习2-5,误差控制可能达到非无效函数c的末尾,c,C,编写函数any(s1,s2),它返回字符串s1中的第一个位置,其中出现了字符串s2中的任何字符;如果s1不包含s2中的任何字符,则返回-1。 当我编译我的代码时,我得到“控件可能会到达非void函数的末尾。导致错误的部分,下面是我的代码: int any(string a,string b){ int i,j; int c = 0; for(i=0;i<strlen(a);i++){ for(j=0;j<strlen(b);j++){
int any(string a,string b){
int i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
return i;
break;
}
}
}
if(c==0)
return -1;
}
int any(字符串a、字符串b){
int i,j;
int c=0;
对于(i=0;i你应该开始学习使用括号,这意味着如果你改变了这一点:
if(c==0)
return -1;
为此:
if(c==0){
return -1;
}
如果C!=0
,您将很容易发现没有返回
另一个问题是:
if(b[j]==a[i]&&c==0){
c = 1;
return i;
break;
}
首先你说returni;
,然后说break
,真的吗
另一件事是关于strlen的,定义如下:
size_t strlen(const char * str){
const char *s;
for (s = str; *s; ++s) {}
return(s - str);
}
size\u t
是long unsigned int
,这意味着:
for(i=0;i<strlen(a);i++)
应该是:
size_t i,j;
或:
因此,即使您修复了该问题,仍然需要进行一些强制转换:
int any(string a,string b){
size_t i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
break;
}
}
}
if(c==1){
return (int)i;
}else{
return (int)-1;
}
}
int any(字符串a、字符串b){
尺寸i,j;
int c=0;
对于(i=0;i您会得到错误,因为编译器不够聪明,无法意识到如果您进行测试,c==0
必须为真。出于同样的原因,测试完全没有必要,因此删除它并在该点返回-1
将修复错误
通过更改为,您可以大大简化:
int any(char * a, char * b){
int i, j;
for( i = 0; a[i]; ++i ) {
for( j = 0; b[j]; ++j ) {
if( b[j] == a[i] ) {
return i;
}
}
}
return -1;
}
这避免了冗余测试,避免了对c
变量的需要,并避免了对strlen()
的不必要的重复调用
typedef
ingchar*
asstring
的品味也很差
对于本练习来说,可能有些过头了,但通过以一些内存效率换取速度效率,您可以将数组设置为查找表,并将b
中的字符读入其中,然后逐步通过a
,直到到达末尾或获得匹配。这需要准确地遍历b
中的字符一次,最多一次完整遍历a
,因此您将得到一个线性时间算法,而不是现在的二次时间算法
例如:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int any(char * a, char * b);
int main(void)
{
printf("'rifle', 'flog': %d\n", any("rifle", "flog"));
printf("'pterodactyl', 'dint': %d\n", any("pterodactyl", "dint"));
printf("'xyzzy', 'fish': %d\n", any("xyzzy", "fish"));
return 0;
}
int any(char * a, char * b)
{
int lookup[CHAR_MAX + 1] = {0};
for ( int i = 0; b[i]; ++i ) {
lookup[b[i]] += 1;
}
for ( int i = 0; a[i]; ++i ) {
if ( lookup[a[i]] ) {
return i;
}
}
return -1;
}
你有什么问题吗?代码不完整,但上一次测试可能为false,那么控件到达函数末尾时没有返回任何值;至少编译器看不到c
必须为0。为什么需要变量c
?试着删除它。返回后也不需要中断您可能会发现“错误”如果您提高编译器优化级别,则测试将消失。但是一个好的解决方案是删除if(c==0)
。如果您确定c
在该点上必须0
,那么测试无论如何都是多余的。谢谢,这非常有用,我从未注意到这一点。
int any(string a,string b){
size_t i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
break;
}
}
}
if(c==1){
return (int)i;
}else{
return (int)-1;
}
}
size_t any(string a,string b){
size_t i,j;
int c = 0;
for(i=0;i<strlen(a);i++){
for(j=0;j<strlen(b);j++){
if(b[j]==a[i]&&c==0){
c = 1;
break;
}
}
}
if(c==1){
return i;
}else{
return 1;
}
}
int any(char * a, char * b){
int i, j;
for( i = 0; a[i]; ++i ) {
for( j = 0; b[j]; ++j ) {
if( b[j] == a[i] ) {
return i;
}
}
}
return -1;
}
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int any(char * a, char * b);
int main(void)
{
printf("'rifle', 'flog': %d\n", any("rifle", "flog"));
printf("'pterodactyl', 'dint': %d\n", any("pterodactyl", "dint"));
printf("'xyzzy', 'fish': %d\n", any("xyzzy", "fish"));
return 0;
}
int any(char * a, char * b)
{
int lookup[CHAR_MAX + 1] = {0};
for ( int i = 0; b[i]; ++i ) {
lookup[b[i]] += 1;
}
for ( int i = 0; a[i]; ++i ) {
if ( lookup[a[i]] ) {
return i;
}
}
return -1;
}
paul@horus:~/Documents/src/sandbox$ ./any
'rifle', 'flog': 2
'pterodactyl', 'dint': 1
'xyzzy', 'fish': -1
paul@horus:~/Documents/src/sandbox$