[字符串操作]挑选最大值序列

2023-12-14 16:04:54

挑选最大值序列

题目描述

给出了若干行非负整数序列,请选择最大值所在的序列,按输入原样输出该序列。如果最大值出现在多个序列,则只输出最大值最后出现的序列。
假设:每个序列中至少有1个整数,至多300个整数,每个整数的长度不超过4位。

关于输入

第1行:整数序列的个数N
后面有 N 个整数序列,每个序列中的整数之间以逗号间隔;

关于输出

按原样输出其中的一个整数序列

例子输入
5
12,13,10,18,108,20
17,20,30,20,36,40,55,86,92
25,66,89,63,66,79
77,79,88,0,076,096,009,008,108
32,63,12,82,068,5
例子输出
77,79,88,0,076,096,009,008,108
解题分析

本题可以一边读入数据,一边寻找最大的值并记录,需要注意的是,本题输入数据带有前导0,这就很讨厌了,我们需要对字符串进行操作,其中使用了strtok,stol函数来帮助我们。

代码实现
#include <iostream>
#include <cstring>
using namespace std;

char nums[10000][305][5];
char array1[1500]; char array2[1500];

int main() {
	int n; scanf("%d",&n);
	int maxN=0,maxi;
	for(int i=0;i<n;i++){
		int k=0;
		char *temp;
		scanf("%s",array1);
		sprintf(array2,",%s,",array1);
	    temp=strtok(array2,",");
		while(temp!=NULL){
		    strcpy(nums[i][k++],temp);
			if(atol(temp)>=maxN){
				maxN=atol(temp);
				maxi=i;
			}
			strcpy(nums[i][k],"-1");
            temp=strtok(NULL,",");
		}
	}
	for(int j=0;strcmp(nums[maxi][j],"-1")!=0;j++){
		if(j==0)
			printf("%s",nums[maxi][j]);
		else
			printf(",%s",nums[maxi][j]);
	}
	return 0;
}

这个程序的主要目标是找出包含最大整数的序列,并且如果有多个序列包含相同的最大整数,则输出最后一个包含该最大整数的序列。程序采用了以下步骤来实现这个目标:

  1. 输入序列的数量:首先,程序从输入中读取整数序列的数量n。

  2. 读取并处理每个序列:然后,程序进入一个循环,对每个序列进行处理。在每次循环中,程序首先读取一个序列(以字符串形式),然后使用strtok函数将序列中的每个整数提取出来,并将其复制到二维字符数组nums中。

  3. 查找最大整数:在提取整数的同时,程序使用atol函数将整数从字符串形式转换为长整数形式,并与当前的最大整数maxN进行比较。如果找到了一个更大的整数,或者找到了一个与maxN相等但出现在更后面的序列中的整数,程序就更新maxNmaximaxi是包含最大整数的序列的索引)。

  4. 输出包含最大整数的序列:最后,程序输出包含最大整数的序列。它通过遍历nums[maxi]数组来实现这一点,直到遇到"-1"(这是每个序列的结束标志)。

程序的主要思路是:在读取和处理每个序列的同时,找出包含最大整数的序列。这样,当所有序列都处理完后,程序就可以直接输出结果,无需再进行额外的搜索或比较操作。这是一种典型的"一边处理,一边查找最优解"的策略,可以有效地减少计算和存储需求。

进一步拓展

trtok是C语言中的一个函数,用于分割字符串。其函数原型为:

char *strtok(char *str, const char *delim);

这个函数接受两个参数:一个是待分割的字符串str,另一个是作为分隔符的字符串delim。函数返回一个指向下一个分割出的子串的指针。如果没有更多的子串可分割,那么函数返回NULL。

strtok的工作原理是:在str字符串中找到第一个delim中包含的字符,然后将这个字符替换为\0,并将指针指向这个字符后面的第一个字符。如果str已经是NULL,那么strtok会从上次分割的位置开始,继续查找下一个分隔符。

需要注意的是,strtok在使用时会修改原始字符串,所以如果你不希望原始字符串被修改,那么在使用strtok之前,应该先将原始字符串复制到另一个缓冲区。

程序中,strtok函数用来分割每个输入的整数序列。每个序列是一个以逗号分隔的整数列表,如"12,13,10,18,108,20"。

首先,程序将每个输入序列作为一个字符串读入。然后,这个字符串被复制到另一个字符串array2中,并在其前后添加了逗号。这样做的目的是确保strtok可以正确地分割出序列中的第一个和最后一个整数。

然后,程序调用strtok函数,以逗号作为分隔符来分割array2

temp=strtok(array2,",");

strtok函数在这里的作用是找到array2中的第一个逗号,并将其替换为\0,然后返回一个指向array2的指针。这个指针指向的就是序列中的第一个整数。

在后续的调用中,strtok的第一个参数是NULL,这表示strtok应该从上次分割的位置开始,继续查找下一个逗号,并返回一个指向下一个整数的指针:

temp=strtok(NULL,",");

strtokarray2中找不到更多的逗号时,它会返回NULL。这时,程序知道已经处理完了当前的整数序列,可以开始处理下一个序列。

总的来说,strtok在你的程序中的作用是把每个输入序列分割成一系列的整数,以便程序可以逐个处理这些整数。

sprintf是C语言中的一个函数,用于将格式化的数据写入字符串。它是printf函数的一种变体,只不过printf是将格式化的数据写入标准输出(通常是屏幕),而sprintf则是将格式化的数据写入字符串。

sprintf的函数原型为:

int sprintf(char *str, const char *format, ...);

这个函数接受一个字符串指针str作为第一个参数,一个格式字符串format作为第二个参数,然后是一个可变数量的额外参数。函数会根据format字符串来格式化额外的参数,并将结果写入str字符串。函数返回写入的字符数量(不包括最后的空字符)。

format字符串可以包含普通的字符和格式说明符。普通的字符会被原样复制到str字符串,而格式说明符会被替换为额外参数的值。格式说明符以%字符开始,然后是一个或多个格式控制字符。例如,%d表示一个整数,%f表示一个浮点数,%s表示一个字符串等。

例如,下面的代码:

char str[50];
int a = 10;
float b = 3.14;
sprintf(str, "a = %d, b = %f", a, b);

会将字符串"a = 10, b = 3.140000"写入str

除了sprintf外,还有几个相关的函数:

  1. printf:将格式化的数据写入标准输出。

  2. fprintf:将格式化的数据写入文件。它的函数原型为int fprintf(FILE *stream, const char *format, ...);,其中stream是一个文件指针,指向要写入的文件。

  3. snprintf:将格式化的数据写入字符串,但是可以指定最大写入的字符数量。这可以防止写入的数据超过字符串的大小,从而导致缓冲区溢出。它的函数原型为int snprintf(char *str, size_t size, const char *format, ...);,其中size是最大写入的字符数量。

  4. scanffscanfsscanf:这些函数与上面的函数相反,它们是从标准输入、文件、字符串中读取格式化的数据。

这些函数都是C语言中处理输入/输出的重要工具,通过它们,你可以方便地在程序中处理各种数据。

sscanf是C语言中的一个函数,用于从一个字符串中读取格式化的输入。这个函数与scanf类似,只不过scanf是从标准输入(通常是键盘)读取输入,而sscanf则是从一个字符串读取输入。

sscanf的函数原型为:

int sscanf(const char *str, const char *format, ...);

这个函数接受一个字符串str作为第一个参数,一个格式字符串format作为第二个参数,然后是一个可变数量的额外参数。函数会根据format字符串来解析str字符串,并将结果存储到额外的参数中。函数返回成功解析并存储的项的数量。

format字符串可以包含普通的字符和格式说明符。普通的字符(包括空格)必须与str字符串中的字符完全匹配,而格式说明符则用于解析str字符串中的值。格式说明符以%字符开始,然后是一个或多个格式控制字符。例如,%d用于解析一个整数,%f用于解析一个浮点数,%s用于解析一个字符串等。

例如,下面的代码:

char *str = "123 456.789 hello";
int a;
float b;
char c[10];
sscanf(str, "%d %f %s", &a, &b, c);

这段代码会解析字符串"123 456.789 hello",并将解析的结果存储到变量ab和数组c中。解析后,a的值为123,b的值为456.789,c的值为"hello"。

sscanf是一个非常强大的函数,可以用来解析各种格式的字符串。然而,使用它时需要小心,因为如果format字符串和str字符串不匹配,或者额外的参数不足以存储解析的结果,那么可能会导致未定义的行为。

在C语言中,我们有一些函数可以将字符串转换为不同类型的数字:

  1. atoi:这个函数将字符串转换为int类型的整数。其函数原型为:

    int atoi(const char *str);
    

    这个函数会扫描参数str字符串,跳过前面的空白字符,直到遇到第一个非空白字符。然后,如果这个字符是一个有效的整数字符(如一个数字或正负号),函数会继续扫描,直到遇到一个无效的整数字符为止。然后,函数会将这个整数字符序列转换为一个int值。

  2. atolatoll:这两个函数的功能与atoi类似,只不过它们分别将字符串转换为longlong long类型的整数。

  3. atof:这个函数将字符串转换为double类型的浮点数。其函数原型为:

    double atof(const char *str);
    

    这个函数的工作原理与atoi类似,只不过它会将整数字符序列转换为一个double值。

下面是一个使用atoiatof的例子:

char *str1 = "123";
char *str2 = "456.789";
int num1 = atoi(str1);
double num2 = atof(str2);

在这个例子中,num1的值为123,num2的值为456.789。

除了上述函数,你还可以使用sscanf函数来解析更复杂的字符串。sscanf函数可以根据一个格式字符串来解析输入字符串,并将结果存储到指定的变量中。例如:

char *str = "123 456.789";
int num1;
double num2;
sscanf(str, "%d %lf", &num1, &num2);

在这个例子中,sscanf函数会将字符串"123 456.789"解析为一个整数和一个浮点数,然后将这两个数的值分别存储到num1num2中。解析后,num1的值为123,num2的值为456.789。

这些函数为在C语言中处理字符串和数字之间的转换提供了强大的工具,但是使用它们时需要注意,如果输入字符串不是一个有效的数字,那么这些函数可能会产生不可预期的结果。

文章来源:https://blog.csdn.net/StudyingPanda/article/details/134994888
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。