[英]Removing consecutive repeated characters from string using C
I'm trying to remove consecutive repeated characters from a given string. 我正在尝试从给定的字符串中删除连续的重复字符。
Example: 例:
bssdffFdcrrrtttii ***# bssdffFdcrrrtttii ***#
output is supposed to be: 输出应该是:
bsdfFdcrti *# bsdfFdcrti *#
This code doesn't work and only prints the first char (b), I want to learn about my mistake. 此代码无效,仅输出第一个字符(b),我想了解我的错误。 when I'm doing a printf test, it works but not for spaces. 当我进行printf测试时,它可以工作,但不能用于空格。 I think the problem might be with the new char array. 我认为问题可能出在新的char数组上。
void Ex6() {
char* string[80];
scanf("%s", &string);
puts(removeDup(string));
}
char* removeDup(char *string) {
int i, c = 0;
char* newString[80];
for (i = 0; i < strlen(string); i++) {
if (string[i] != string[i + 1]) {
newString[c++] = string[i];
}
}
return newString;
}
There are several problems with your program: 您的程序有几个问题:
newString
should be char newString[80]
, ie, an array of characters and not an array of pointers-to-characters, and likewise for the declaration in Ex6
. newString
的声明应为char newString[80]
,即,一个字符数组,而不是一个指向字符的指针数组,同样对于Ex6
的声明。 scanf
should then be scanf("%s", string)
, since string
is already the address of an array of characters, but... 然后,对scanf
的调用应为scanf("%s", string)
,因为string
已经是字符数组的地址,但是... fgets
to read a string from the user to ensure that you read whitespace, if it's important, and that the buffer is not exceeded. 使用fgets
从用户读取字符串,以确保您读取空格(如果很重要),并且不超过缓冲区。 newString
is allocated on the stack and so should not be returned to the caller. newString
是在堆栈上分配的,因此不应返回给调用方。 It is better to do a char *newString = strdup(string)
, or, slightly less sloppy, char *newString = malloc(strlen(string)+1)
, which will call malloc
for a block of memory sufficient to hold the original string, and thus the version without duplicates -- the comments rightly point out that this could be optimized. 最好做一个char *newString = strdup(string)
,或者稍微少一点草率的char *newString = malloc(strlen(string)+1)
,这将调用malloc
以获得足以容纳原始字符串的内存块,因此没有重复的版本-注释正确地指出可以对其进行优化。 In principle, the caller, ie, Ex6
, must free
the returned pointer to avoid a memory leak but it hardly matters in such a short program. 原则上,调用者(即Ex6
)必须free
返回的指针,以避免内存泄漏,但是在如此短的程序中这无关紧要。 newString[c] = '\\0'
. 结果需要一个空终止符: newString[c] = '\\0'
。 Otherwise, the removeDup
function seems to work correctly. 否则, removeDup
函数似乎可以正常工作。
So, putting all of that together: 因此,将所有这些放在一起:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* removeDup(const char *string)
{
size_t i, c = 0;
size_t string_len = strlen(string);
char *newString = malloc(string_len + 1);
for (i = 0; i < string_len; i++) {
if (string[i] != string[i + 1]) {
newString[c++] = string[i];
}
}
newString[c] = '\0';
return newString;
}
#define MAX_STRING_LEN 80
void Ex6() {
char string[MAX_STRING_LEN];
char* result;
if (fgets(string, MAX_STRING_LEN, stdin) != NULL) {
result = removeDup(string);
printf("%s", result);
free(result);
}
}
Finally, I agree with @tadman's comment. 最后,我同意@tadman的评论。 Since the input string must anyway be traversed to calculate the length, we may as well optimize the size of the result string: 由于无论如何都必须遍历输入字符串以计算长度,因此我们也可以优化结果字符串的大小:
char* removeDup(const char *string)
{
size_t i, c = 0;
char *newString;
for (i = 0; string[i] != '\0'; i++)
c += (string[i] != string[i + 1]);
newString = malloc(c + 1);
for (i = c = 0; string[i] != '\0'; i++) {
if (string[i] != string[i + 1]) {
newString[c++] = string[i];
}
}
newString[c] = '\0';
return newString;
}
There are quite a few issues in your program. 您的程序中有很多问题。 It wouldn't even compile let alone run. 它甚至不会编译,更不用说运行了。 Also, the most problematic issue is that you are returning a pointer to a local variable from a function that ceases its scope upon completion. 同样,最有问题的问题是,您正在从函数返回指向局部变量的指针,该函数在完成时会终止其作用域。 A simplified version of your program is as follows: 程序的简化版本如下:
void Ex6()
{
char string[80];
scanf("%s", string);
int i, c = 0;
char newString[80];
for (i = 0; i < strlen(string); i++) {
if (string[i] != string[i + 1]) {
newString[c++] = string[i];
}
}
newString[c] = '\0';
puts(newString);
}
You can do it with O(n) time and O(1) space, by modifying existing string: 您可以通过修改现有字符串来使用O(n)时间和O(1)空间来实现:
#include <stdio.h>
char* removeDup(char* input) {
char* newTail = input, *oldTail = input;
while (*oldTail) {
if (*newTail == *oldTail) {
++oldTail;
} else {
*++newTail = *oldTail++;
}
}
return newTail;
}
int main() {
char string[] = "bssdffFdcrrrtttii ***#";
char* newEnd = removeDup(string);
char* tmp = string;
while (tmp != newEnd) {
printf("%c", *tmp++);
}
//Print the last char if string had any duplicates
if(*tmp) {
printf("%c", *tmp++);
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.