#c #string #c-strings
#c #строка #c-строки
Вопрос:
Мне нужно удалить все буквы, из s1
которых есть s2
. Я не могу понять, что не так с моим кодом:
#include <stdio.h>
#include <stdlib.h>
void squeeze(char s1[], char s2[])
{
int i,j;
i=j=0;
for(i; s2[i]!=''; i ) {
for (j; s1[j] != ''; j ) {
if (s1[j] == s2[i]) {
s1[j] = s1[j 1];
--j;
}
}
}
}
int main()
{
char w1[] = "abcde";
char w2[] = "fghaj";
squeeze(w1,w2);
puts(w1);
return 0;
}
но вывод:
abcde
Что я должен исправить?
Комментарии:
1. Вы пробовали пошагово выполнять код оператор за оператором в отладчике? О чем это вам говорит?
2. я новичок, поэтому мне это ничего не говорит, более того, я никогда раньше не использовал debugger
3. Тогда используйте это как идеальное время, чтобы узнать , как использовать отладчик. Возможность использования отладчика действительно обязательна, если вы хотите выполнять какое-либо программирование.
4. спасибо, я это увижу
5. Или, прежде чем связываться с отладчиком, попробуйте просто добавить операторы printf в свой алгоритм, чтобы вы могли получить бумажный отчет, показывающий, как продвигался алгоритм. Это более универсальный способ отладки вашей программы, поскольку интерфейсы отладчика различаются.
Ответ №1:
Для начала переменная j
не сбрасывается 0
во внутренний цикл для каждой итерации внешнего цикла.
Во-вторых, если символ должен быть удален, то все символы после него не перемещаются влево на одну позицию. Вы просто заменяете удаленный символ следующим символом в строке.
Функция может выглядеть следующим образом, как показано в демонстрационной программе ниже.
#include <stdio.h>
#include <string.h>
char * squeeze( char s1[], const char s2[] )
{
for ( char *p = s1, *q = s1; *q; p )
{
if ( !*p || !strchr( s2, *p ) )
{
if ( q != p )
{
*q = *p;
}
if ( *p ) q;
}
}
return s1;
}
int main( void )
{
char w1[] = "abcde";
char w2[] = "fghaj";
puts( squeeze( w1, w2 ) );
return 0;
}
Вывод программы
bcde
Если вам не разрешено использовать стандартные строковые функции и указатели, то программа может выглядеть следующим образом.
#include <stdio.h>
char * squeeze( char s1[], const char s2[] )
{
for ( size_t i = 0, j = 0; s1[j] != ''; i )
{
size_t k = 0;
while ( s2[k] != '' amp;amp; s2[k] != s1[i] ) k;
if ( s2[k] == '' )
{
if ( j != i )
{
s1[j] = s1[i];
}
if ( s1[i] != '' ) j;
}
}
return s1;
}
int main( void )
{
char w1[] = "abcde";
char w2[] = "fghaj";
puts( squeeze( w1, w2 ) );
return 0;
}
Вывод программы такой же, как показано для предыдущей демонстрационной программы
bcde
Комментарии:
1. спасибо, но я должен сделать это без указателей / индикаторов
2. @HGH Что такое индикатор?
3. я имею в виду ‘ * » просто не знаю, как сказать это по-английски, может быть, указатель? индекс?
Ответ №2:
Две проблемы в squeeze
:
- Вам нужно повторно инициализировать
j
до нуля при каждом проходе через цикл. - Вам нужно скопировать всю оставшуюся часть строки на один символ влево, а не только символ, следующий за тем, который вы хотите удалить.
Я предлагаю вам переписать squeeze
как:
void squeeze(char s1[], char s2[])
{
int i,j;
i=j=0;
for( ; s2[i]!=''; i ) {
for (j = 0; s1[j] != ''; j ) {
if (s1[j] == s2[i]) {
strcpy(s1 j, s1 j 1);
--j;
}
}
}
}
Комментарии:
1. хорошо, спасибо, но как это сделать без ‘strcpt’?
2. Напишите другой цикл, чтобы делать то, что
strcpy
делает.3. я пытаюсь: void squeeze(char s1[], char s2[]) { int i, j,k; for(i= 0; s2[i]!=»; i ) { for (j = 0; s1[j] != »; j ) { if (s1[j] == s2[i]) { for(k= j; k != »; k ) { s1[k] = s1[k 1]; } } } } }
4. @Bob Jarvis — Восстановить Monica Предоставленный код с strcpy имеет неопределенное поведение.
Ответ №3:
Я вижу здесь проблему, ваш код по какой-то причине не вводит этот оператор :
if (s1[j] == s2[i]) {
s1[j] = s1[j 1];
--j;
}
ваш вопрос может быть почему? поскольку для i и j не задано значение 0, попробуйте распечатать их, и вы увидите, что j переместится на 4, но i навсегда останется равным 0
, поэтому для начала вы можете исправить это, выполнив это
for(i=0; s2[i]!=''; i ) {
for (j=0; s1[j] != ''; j ) {
затем вы не скопировали всю строку и переместили ее на один шаг назад, чтобы переписать найденный символ, вы переместили только один символ и оставили его пустым
Exemple
input : abcde
output :b_cde
чтобы исправить это, у вас есть два метода :
используйте strcpy
, чтобы переместить код на один шаг назад
for(i=0; s2[i]!=''; i ) {
for (j=0; s1[j] != ''; j ) {
if (s1[j] == s2[i]){
strcpy(s1 j, s1 j 1);
--j;
}
}
или вы можете просто создать ту же функцию, используя букле для
for(i=0; s2[i]!=''; i ) {
for (j=0; s1[j] != ''; j ) {
if (s1[j] == s2[i]){
for (k=j;s1[k] != '';k )
s1[k] = s1[k 1];
--j;
}
}
Комментарии:
1. спасибо, но как это сделать без ‘strcpy’? я знаю, что я должен использовать третий цикл, но я не знаю как…
2. @HGH Я не уверен, видите ли вы последнюю часть, попробуйте обновить страницу, поскольку я уже писал о том, как использовать ту же функцию strcpy, используя для букле
3. да, страница не обновлялась, теперь я вижу, большое спасибо!
4. @HGH я рад, что мне удалось вам помочь. Не сдавайтесь и попытайтесь использовать больше примеров для достижения вашего решения
5. @HGH это работает на моей стороне, я попытался изменить строку. Пожалуйста, предоставьте больше информации, чтобы отследить проблему
Ответ №4:
#include <stdio.h>
#include <string.h>
int rem_str(char * porgstr, char * pdel) {
if (!porgstr || !pdel) {
return 0;
}
int i = 0;
int j = 0;
char tmp[256] = {0};
int len = strlen(pdel);
for (i = 0; i < len; i ) {
tmp[pdel[i]] ;
}
len = strlen(porgstr);
for (i = 0, j=0; i < len; i ) {
if(tmp[porgstr[i]] == 0) {
porgstr[j] = porgstr[i];
j ;
}
}
porgstr[j] = 0;
return 0;
}
int main () {
char * input1 = strdup("origional string passed to program");
char * input2 = strdup("sdel");
printf("Input before del : %sn", input1);
rem_str(input1, input2);
printf("String after del : %sn", input1);
return 0;
}
Вывод:
./a.out
Input before del : origional string passed to program
string after del : origiona tring pa to program