数组中的字符串顺序
Strings order in Array
我有下一个代码,
如您所料,我希望看到最后一行的输出:a , b ,c ,d
但实际输出是:
a d (null) (null)
a c d (null)
a b c d
a b b c
最后一行,为什么我看到了?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char **str = calloc(4, sizeof(char *));
str[0] = str_tmp[0];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str[j]) < 0)
{
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < 4; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
}
}
return 0;
}
原因是这一行str[j] = str_tmp[i];
仍然存在的最少元素是b
,你需要交换它
请使用简单的方法进行交换
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char *temp = "";
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str_tmp[j]) < 0)
{
temp = str_tmp[i];
str_tmp[i] = str_tmp[j];
str_tmp[j] = temp;
}
}
}
for (int n = 0; n < 4; n++)
{
printf("%s ", str_tmp[n]);
}
return 0;
}
问题是这个循环
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str[j]) < 0)
{
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < 4; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
}
当 if 语句中的条件
时不停止其迭代
if (strcmp(str_tmp[i], str[j]) < 0)
满意。
所以当目标数组中有以下值时
a c d (null)
那么对于 j 等于 1 的条件
strcmp(str_tmp[i], str[j]) < 0
计算结果为真,结果得到
a b c d
但是循环继续它的迭代并且对于 j 再次等于 2 条件
strcmp(str_tmp[i], str[j]) < 0
返回 true 结果元素 str_tmp[i[ 被插入到位置 2 并且你得到
a b b c
你必须在条件满足时立即中断循环。
这是您更新后的程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char **str = calloc(4, sizeof(char *));
str[0] = str_tmp[0];
for (int i = 0; i < 4; i++)
{
int j = 0;
while ( j < i && !( strcmp(str_tmp[i], str[j]) < 0 ) ) j++;
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < i + 1; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
free( str );
return 0;
}
它的输出是
d
a d
a c d
a b c d
其实一个循环是多余的。使用像 4 这样的幻数也是一个坏主意。程序可以按以下方式重写
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *str_tmp[] = { "d", "a", "c", "b" };
const size_t N = sizeof( str_tmp ) / sizeof( *str_tmp );
char **str = calloc( N, sizeof( char * ) );
for ( size_t i = 0; i < N; i++ )
{
size_t j = i;
for ( ; j != 0 && strcmp( str_tmp[i], str[j-1] ) < 0; j-- )
{
str[j] = str[j-1];
}
str[j] = str_tmp[i];
for ( size_t n = 0; n < i + 1; n++ )
{
printf( "%s ", str[n] );
}
putchar( '\n' );
}
free( str );
return 0;
}
由于现在该程序不依赖于幻数 4,您可以向数组添加任意数量的新元素 tmp_str
并且该程序无需任何其他更改即可运行。例如,如果你用下面的方式
用初始值设定项填充数组 tmp_str
char *str_tmp[] = { "d", "a", "c", "b", "k", "j", "z", "t" };
那么程序输出将是
d
a d
a c d
a b c d
a b c d k
a b c d j k
a b c d j k z
a b c d j k t z
您可以将插入排序方法的代码移到一个单独的函数中。例如
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void insertion_sort( char * s[], size_t n )
{
for ( size_t i = 1; i < n; i++ )
{
if ( strcmp( s[i], s[i-1] ) < 0 )
{
char *item = s[i];
size_t j = i;
do
{
s[j] = s[j-1];
} while ( --j != 0 && strcmp( item, s[j-1] ) < 0 );
s[j] = item;
}
}
}
int main(void)
{
char *s[] = { "d", "a", "c", "b", "k", "j", "z", "t" };
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
insertion_sort( s, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
return 0;
}
我有下一个代码,
如您所料,我希望看到最后一行的输出:a , b ,c ,d
但实际输出是:
a d (null) (null)
a c d (null)
a b c d
a b b c
最后一行,为什么我看到了?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char **str = calloc(4, sizeof(char *));
str[0] = str_tmp[0];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str[j]) < 0)
{
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < 4; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
}
}
return 0;
}
原因是这一行str[j] = str_tmp[i];
仍然存在的最少元素是b
,你需要交换它
请使用简单的方法进行交换
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ()
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char *temp = "";
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str_tmp[j]) < 0)
{
temp = str_tmp[i];
str_tmp[i] = str_tmp[j];
str_tmp[j] = temp;
}
}
}
for (int n = 0; n < 4; n++)
{
printf("%s ", str_tmp[n]);
}
return 0;
}
问题是这个循环
for (int j = 0; j < i; j++)
{
if (strcmp(str_tmp[i], str[j]) < 0)
{
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < 4; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
}
当 if 语句中的条件
时不停止其迭代 if (strcmp(str_tmp[i], str[j]) < 0)
满意。
所以当目标数组中有以下值时
a c d (null)
那么对于 j 等于 1 的条件
strcmp(str_tmp[i], str[j]) < 0
计算结果为真,结果得到
a b c d
但是循环继续它的迭代并且对于 j 再次等于 2 条件
strcmp(str_tmp[i], str[j]) < 0
返回 true 结果元素 str_tmp[i[ 被插入到位置 2 并且你得到
a b b c
你必须在条件满足时立即中断循环。
这是您更新后的程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *str_tmp[4] = {"d", "a", "c", "b"};
char **str = calloc(4, sizeof(char *));
str[0] = str_tmp[0];
for (int i = 0; i < 4; i++)
{
int j = 0;
while ( j < i && !( strcmp(str_tmp[i], str[j]) < 0 ) ) j++;
for (int k = i; k > j; k--)
{
str[k] = str[k-1];
}
str[j] = str_tmp[i];
for (int n = 0; n < i + 1; n++)
{
printf("%s ", str[n]);
}
printf("\n");
}
free( str );
return 0;
}
它的输出是
d
a d
a c d
a b c d
其实一个循环是多余的。使用像 4 这样的幻数也是一个坏主意。程序可以按以下方式重写
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char *str_tmp[] = { "d", "a", "c", "b" };
const size_t N = sizeof( str_tmp ) / sizeof( *str_tmp );
char **str = calloc( N, sizeof( char * ) );
for ( size_t i = 0; i < N; i++ )
{
size_t j = i;
for ( ; j != 0 && strcmp( str_tmp[i], str[j-1] ) < 0; j-- )
{
str[j] = str[j-1];
}
str[j] = str_tmp[i];
for ( size_t n = 0; n < i + 1; n++ )
{
printf( "%s ", str[n] );
}
putchar( '\n' );
}
free( str );
return 0;
}
由于现在该程序不依赖于幻数 4,您可以向数组添加任意数量的新元素 tmp_str
并且该程序无需任何其他更改即可运行。例如,如果你用下面的方式
char *str_tmp[] = { "d", "a", "c", "b", "k", "j", "z", "t" };
那么程序输出将是
d
a d
a c d
a b c d
a b c d k
a b c d j k
a b c d j k z
a b c d j k t z
您可以将插入排序方法的代码移到一个单独的函数中。例如
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void insertion_sort( char * s[], size_t n )
{
for ( size_t i = 1; i < n; i++ )
{
if ( strcmp( s[i], s[i-1] ) < 0 )
{
char *item = s[i];
size_t j = i;
do
{
s[j] = s[j-1];
} while ( --j != 0 && strcmp( item, s[j-1] ) < 0 );
s[j] = item;
}
}
}
int main(void)
{
char *s[] = { "d", "a", "c", "b", "k", "j", "z", "t" };
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
insertion_sort( s, N );
for ( size_t i = 0; i < N; i++ )
{
printf( "%s ", s[i] );
}
putchar( '\n' );
return 0;
}