给定一个字符串形式的数字,我想从中提取每k个数字。然后遍历剩下的字符串,再次提取第k个数字。我得到的结果应该由这些提取的数量(在一个适当的顺序)。示例:123456789,k = 3——>369485271
我的算法如下:字符串的长度允许提取每k个数字,我遍历字符串并将每k个元素存储在另一个字符串中。然后,我通过跟踪元素的适当索引从原始字符串中删除提取的元素,并在str的长度足够时继续执行。我不明白有什么问题我的代码。也许我的方法不是很好,有一些变速器这更好的/更简单的方法吗?
#include <stdio.h>
#include <string.h>
void remove(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != ' '; *src = *(src+1),++src) ;
*src = ' ';
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
while (strlen(number)>k-1) {
for (int i = 0, p = 0; number[i] != ' '; i++) {
if (i % k == (k-1)) {
result[p] = number[i];
p++;
}
}
for (int j = 0; number[j] != ' '; j++){
if (j % k == (k-1)) {
remove(number, j);
j+=1; /*since the index was shifted due to removing an element*/
}
}
}
puts(result);
return 0;
}
你的一些问题:
- 在
while
循环的每次迭代中重新开始编写输出。 - 不处理最后数字
- 不将输入视为循环输入。
- 你没有终止你的输出字符串。
remove
已经是标准库函数的名称。
更短的版本可以是这样(未经测试):
#include <stdio.h>
#include <string.h>
void remove_digit(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != ' '; *src = *(src+1),++src)
;
}
int main() {
char number[100];
char result[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
int i = 0;
int skip = k-1; // We remove 1 digit and skip k-1 digits
while (number[0] != 0) {
i = (i + skip) % strlen(number);
result[p] = number[i];
p++;
remove_digit(number, i);
}
number[p] = 0;
puts(result);
return 0;
}
下面的代码似乎是您想要的:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void remove_(char *str, unsigned int index) {
char *src;
for (src = str+index; *src != ' '; *src = *(src+1),++src) ;
*src = ' ';
}
int main(int argc, const char * argv[]) {
char number[100];
char result[100];
int tmp[100];
int k;
printf("Enter a string: ");
scanf("%s",number);
printf("Enter a key: ");
scanf("%d",&k);
int p = 0;
for (int tp = 0; strlen(number) > k-1; tp = 0) {
for (int i = 0; number[i] != ' '; i++)
if (i % k == (k-1))result[p++] = number[i];
for (int j = 0; number[j] != ' '; j++)
if (j % k == (k-1)) tmp[tp++] = j;
for (; tp; --tp) remove_(number, tmp[tp-1]);
}
// The newly added code
for (int index; strlen(number); ) {
index = (k-1) % strlen(number);
result[p++] = number[index];
remove_(number, index);
}
puts(result);
return 0;
}
最重要的是,每个while循环,您需要立即删除number
中的元素。在确保原始代码的完整性的同时,我做了一些更改。不幸的是,原代码的主要思想是错误的。
一轮后从尾部(包括其余部分)到头部循环。但是我发现你提供的代码的功能是,每轮之后,下一轮从头部的第0个元素开始。
顺便说一下,你的算法和约瑟夫斯问题很相似