C语言:如何使用string从n中找到数字创建的最大的数



问题:求n (n<10 ^50)中的数字产生的最大和最小的数。我试过像下面这样,但在某些情况下,它是错误的

例如:

情形1:输入2015输出5210

案例2:Input47356359122Output(错误答案)请帮帮我,我不知道为什么我得到了错误的答案!!

#include <stdio.h>
#include <string.h>
void max(char s[]) {
int l = strlen(s);
int i, key, j;
for (i = 1; i < l; i++) {
key = s[i];
j = i - 1;

while (j >= 0 && s[j] > key) {
s[j + 1] = s[j];
j = j - 1;
}
s[j + 1] = key;
}
s[l - 1] = '';
printf("%sn", s);
}
int main() {
char s[100];
fgets(s, sizeof(s), stdin);
max(s);
}

你的方法是正确的:按降序排序,从这些数字中产生最大的数字。

你的实现有缺陷:

  • 实际上是按递增顺序排序的。您应该将while (j >= 0 && s[j] > key)更改为

    while (j >= 0 && s[j] < key)
    
  • 空终止符设置在错误的位置:您清除s中的最后一个字符。如果从stdin中读取的行以换行符结束,则可能擦除它,除非用户键入了TAB字符,但如果输入仅由数字组成,则将删除最后一个。将代码改为:

    s[l - 1] = '';
    

这是另一种使用计数排序的方法:

#include <stdio.h>
void max_number(char s[]) {
/* array to store the number of occurrences of each digit */
int count[10] = { 0 }; 
int i, d, c;
/* enumerate all characters from the string, stop at the null terminator */
for (i = 0; s[i]; i++) {
/* only count digits from '0' to '9' */
if (s[i] >= '0' && s[i] <= '9') {
/* increase the digit count for this digit */
count[s[i] - '0']++;
}
}
/* output the digits from highest to lowest */
for (i = 0, d = 10; d --> 0;) {
for (c = count[d]; c --> 0;)
s[i++] = '0' + d;
}
if (i == 0) {
/* there were no digits in the string: store a 0 */
s[i++] = '0';
}
if (s[0] == '0') {
/* there were only zeroes in the string: keep a single 0 */
i = 1;
}
/* set the null terminator */
s[i] = '';
printf("%sn", s);
}
int main() {
char s[100];
if (fgets(s, sizeof(s), stdin))
max_number(s);
return 0;
}

用户chqrlie已经提供了一个很好的一般性答案。下面是一种更简单、效率略低的方法。

注意到没有必要实际地将结果存储在一个新的字符串中,您也可以在找到数字时打印数字——从高到低。这个程序在输入字符串上循环10次,首先打印所有的9s,然后是所有的8s,等等。

#include <stdio.h>
void max(char *str) {
for (char digit = '9'; digit >= '0'; --digit) // Assume ASCII
for (char *strCp = str; *strCp != '' ; ++strCp)
if (*strCp == digit)
putchar(digit);
putchar('n');
}
int main(void) {
char s[100];
if (fgets(s, sizeof(s), stdin) != NULL)
max(s);
}

注意:

  • 不使用strlen功能,因此不再需要string.h标头。
  • main签名修改为int main(void),在不使用参数的情况下,这是标准建议的。
  • 检查fgets的返回值,使程序可以处理空输入和输入失败。

对于初学者,该函数不应该输出任何消息。决定是否输出消息的是函数的调用者。

函数应返回一个修改后的字符串,该字符串按降序排序为数字。

当一个空字符串被传递给

函数时,你的函数可以调用未定义的行为
void max(char s[]) {
int l = strlen(s);
int i, key, j;
//...
s[l - 1] = '';
printf("%sn", s);
}

因为在这个语句中

s[l - 1] = '';

试图访问传入字符串之外的内存。一般来说,这个语句是错误的,因为结束的零必须出现在位置l

不需要设置终止零字符'',因为它已经存在于字符串中。所以上面的语句是多余的。

实际上,由于if语句中的条件,您正在尝试使用插入排序方法按升序对字符串中的字符进行排序。

while (j >= 0 && s[j] > key) {

在这种情况下,在调用函数fgets之后出现在字符串中的新行字符'n'将被移动到字符串的开头。

您必须按降序对字符串进行排序。

在调用函数之前,应该从字符串中删除新的行字符'n'

函数可以如下例中所示的方式声明和定义。

#include <stdio.h>
#include <string.h>
char * max_number( char *s )
{
if ( *s )
{
for ( char *p = s + 1; *p; ++p )
{
char c = *p;
char *q = p;

for ( ; q != s && *( q - 1 ) < c; --q )
{
*q = *( q - 1 );
}

if ( q != p ) *q = c;
}
}
return s;
}
int main(void) 
{
char s[100];

fgets( s, sizeof( s ), stdin );

s[ strcspn( s, "n" ) ] = '';

puts( max_number( s ) );

return 0;
}

如果使用fgets输入数字47356359122,则程序输出将为

97655433221

相关内容

  • 没有找到相关文章

最新更新