IMHO.WS

IMHO.WS (http://www.imho.ws/index.php)
-   Программирование (http://www.imho.ws/forumdisplay.php?f=40)
-   -   есть еще пара задач с которыми у меня не получается справиться, помогите!!! (http://www.imho.ws/showthread.php?t=33609)

Izzyy 03.07.2003 04:29

есть еще пара задач с которыми у меня не получается справиться, помогите!!!
 
заголовок ф-ции
void set_replace(unsigned long *n, int j, int i)
нужно сделать так чтобы ф-ция меняла цифры под индексами i и j местами и опять же нужно сделать с помощью рекурсивного вызова ф-ции

int g(char *s1, char *s2)
{
char *p1, *p2;

for (p1=s1;*p1;p1++)
{
for (p2=s2;*p2;p++)
if (*p1==*p2) break;
if (!*p2) break;
}
return p1-p2;
}
кто нить объясните что эта ф-ция делает и что она возвращает что будет если убрать (!*р2) break; и что она после этого возвращать начнет, ну и конечно не плохо было бы ее заменить на рекурсионную ф-цию.

Народ кто знает что с этим всем делать помогите, я уже 3 сутки сижу над книгами и в инете, а толком не дошел до нормальных ответов.
это домашка от которой очень многое зависит, и сдавать мне ее нужно через 4 часа.
Спасите плиз!!!

Izzyy 03.07.2003 04:34

не дайте погибнуть студенту
 
не дайте умереть молодым помогите!!!

alexey_ma 03.07.2003 23:01

>>заголовок ф-ции
>>void set_replace(unsigned long *n, int j, int i)
>>нужно сделать так чтобы ф-ция меняла цифры под индексами i и j местами и >>опять же нужно сделать с помощью рекурсивного вызова ф-ции
Не понятно что ты хочешь сделать.
Зачем тебе рекурсия? Чтобы поменять значения в массиве по известным индексам достаточно сделать так:

void set_replace(unsigned long *n, int j, int i)
{
unsigned long tmp = n[j];
n[j]=n[i];
n[i]=tmp;
}

Только перед вызовом такой функции не мешало бы проверить что индексы за границу массива не выходят.

Machine 04.07.2003 00:06

Цитата:

void set_replace(unsigned long *n, int j, int i)
Интерфейс описан некорректно. Нужно передать в функцию размер массива для проверки.

А по реализации alexey_ma все написал.

Цитата:

кто нить объясните что эта ф-ция делает и что она возвращает что будет если убрать (!*р2) break; и что она после этого возвращать начнет, ну и конечно не плохо было бы ее заменить на рекурсионную ф-цию.
Нда, плохо, что здесь форматированный код не постится :(

Функция в цикле проверяет, что все символы, содержащиеся в первой строке, содержатся и во второй. Но вот возвращает она полную чушь - разность между двумя указателями. Смысла нет.
Может ты перепутал, и там должно было быть:
"return *p1 - *p2" ?
Если так, то функция вернет 0, если проверка успешная и не 0 в противном случае.

Если убрать "if (!*p2) break", то разность (*p1 - *p2) перестанет что-либо отражать.

Рекурсия тут совершенно неуместна.

alexey_ma 04.07.2003 00:24

Точно. "return p1-p2;" - это бред. "return *p1 - *p2" - это правильно. Только функция возвращает не 0,а если проверка успешная то отрицательное значение, а если не успешна то положительное.

Machine 04.07.2003 00:54

alexey_ma
Не могу согласиться :) Проверка успешная будет в том случае, когда *p1 окажется равным *p2. Алгоритм ведь основан на том, что в случае успеха каждый раз будет срабатывать брейк:

if (*p1 == *p2) break;

Выход из алгоритма произойдет:

1. Когда (*p1 == *p2) и (*p2 == '\0') - это случай, когда все проверки были успешными. На выходе получим 0.

2. Когда брейк не сработал и (*p2 == '\0') - проверка не удалась, на выходе разность - какой знак у нее мы не знаем, но это точно не 0.

alexey_ma 04.07.2003 01:43

Не совсем так.
Например возьмем строки "AJ1" и "12J1B23A". Выход произойдет после первого break, *p1 будет равен '\0' , а *p2 будет равен '1' (последний найденный во второй строке символ), на выходе имеем 0-49 = -49 ('\0' - '1'). Хотя проверка успешна и все символы первой строки есть во второй.

Неуспешная проверка:
Изменим строки - "AZ1" и "12J1B23A". 'Z' не будет найден и выход произойдет после второго break. *p1 останеться на 'Z' , а второй for промотает *p2 до '\0'.
на выходе имеем 90-0 = 90 ('Z' - '\0' ).

Machine 04.07.2003 03:29

alexey_ma
:up: Прав! Я туплю =)

Izzyy 07.07.2003 20:06

Что препод дал то и спрашиваю, т.к. самому не понятно.
 
в ф-ции заголовок unsigned long *n n- это не масив, а указатель на число.
а насчет второй ф-ции может рекурсия и безсмыслена только вот все равно хотел бы узнать как это делаетсь, если это не так уж трудно и замарочено.

Izzyy 07.07.2003 20:13

Что препод дал то и спрашиваю, т.к. самому не понятно.
 
в ф-ции заголовок unsigned long *n n- это не масив, а указатель на число.
а насчет второй ф-ции может рекурсия и безсмыслена только вот все равно хотел бы узнать как это делаетсь, если это не так уж трудно и замарочено.

alexey_ma 07.07.2003 22:19

>>в ф-ции заголовок unsigned long *n n- это не масив, а указатель на число.

Тогда вообще нечего непонятно. А где-же массив? Индексы к чему?

А вторую функцию с рекурсией можно сделать так :
Код:

int g(char *s1, char *s2)
{
        char* p2=s2;

        if(!*s1 )
                return (*s1 - *p2);       
        for (p2=s2;*p2;p2++)
                if (*s1==*p2)
                        return g(++s1,s2);
        return (*s1 - *p2);
}

Не проверял. Сам проверь. Должно работать.

Izzyy 08.07.2003 00:21

а что тут не понятно?
у тебя есть число, число состоит как правило из нескольких скажем цифер например 1234567890 ок.
тогда 0 занимает первую позицию в этом числе а 2 занимает 9 место. тогда вызов ф-ции с этим числом и этими параметрами
дает нам 1034567892 т.е. поменял 0 с 2-кой.:idontnow:
вот я и не знаю как сие можно сделать без рекурсии проблем нет делишь число на отдельные части, а потом в нужном порядке и склеиваешь, а вот с рекурсией мне гораздо труднее, т.к. у меня даже идеии нет как тут можно все повернуть.
может мысля какая и есть только она так глубоко, что мне ее вытащить не удается.
я уже даже домашку сдал без этого задания только вот люьопытство мучает меня. надеюсь в каком нить форуме услышать решение.

alexey_ma 08.07.2003 00:51

Теперь понятно. Но только не знаю каким боком тут рекурсию приткнуть.
Вообще твои задачки не подходят под рекурсию. На пример в функции g нужно все время знать указатель на первый элемент второго массива (s2), то есть продвигать этот указатель в рекурсии нельзя. Вот если бы эта функция проверяла не только наличие всех символов первой строки во второй, но и порядок их следования тогда рекурсия как раз уместна. И можно было бы сделать примерно так:
Код:

int g(char* s1, char* s2)
{
        if(!*s1 || !*s2)
                return (*s1 - *s2);       
        if (*s1==*s2)
                return g(++s1,s2);
        else               
                return g(s1,++s2);       
}



Часовой пояс GMT +4, время: 14:49.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.