Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 19, средняя оценка - 4.74
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
#1

Выяснить, сколько чисел входит в последовательность по одному разу - C++

29.10.2011, 16:54. Просмотров 2734. Ответов 30
Метки нет (Все метки)

Условие задачи написано в шапке кода программы. Я написал эту программу, программа работает. Но есть одно ключевое но: преподаватель мне сказал, что то, работает или нет программа его волнует в последнюю очередь. Он анализирует код и задаёт мне постоянно один и тот же вопрос: "какой смысл сравнивать с незаданным b[j]?". Я задавал b[j], равный 0, программа тоже работала, но тогда он мне задал вопрос: "ты сравниваешь все числа с b[j], равным нулю. Какой в этос смысл?". Вот код написанной мною программы:

Код
//Даны натуральное n, целые числа a1, ..., an. Внутри данной последовательности могут быть поваторяющиеся члены. 
//Выяснить, сколько чисел входит в последовательность по одному разу
#include <stdio.h>
const int N=100;
void inMas1(int &n, int a[N])
{
        //ввод размерности массива
        printf ("Vvedite razmernost pervogo massiva n=");
        scanf ("%d", &n);
        //проверка на корректность введённой размерности массива
        if (n<=0)
        {
                printf ("Nekorrektniy vvod \n");
        }
        for (int i=0; i<n; i++)
        {
                //ввод a[i]
                printf ("a[%d]=", i);
                scanf ("%d", &a[i]);
        }
}
void MasNoPovtor(int n, int a[], int &k, int b[])
{
        //начальное присвоение
        k=0;
        //Просмотр массива a[N] с занесением всех неповторяющихся элементов этого массива в b[N]
        for (int i=0; i<n; i++)
        {
                //начальное присвоение
                bool flagNo=true;
                int j=0;
                while ((flagNo)&&(j<n))
                {
                        //цикл сравнения
                        if (a[i]==b[j])
                        {
                                flagNo=false;
                        }
                        j++;
                }
                if (flagNo)
                {
                        //добавление a[i] в b[k]
                        b[k]=a[i];
                        k++;
                }
        }
}
void main()
{
        //определение переменных
        int n, k, a[N], b[N];
        //ввод исходных данных
        inMas1(n, a);
        //вычисление b
        MasNoPovtor(n, a, k, b);
        //вывод результата
        if (n>0)
        {
        printf ("%d", k);
        printf ("\n");
        }
}
Собсно, нужно обосновать этот момент. Либо же, писать программу по-другому. Буду благодарен за помощь
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.10.2011, 16:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выяснить, сколько чисел входит в последовательность по одному разу (C++):

Выяснить, сколько чисел входит в последовательность более чем по одному разу - C++
Даны целые числа а1,...,аn (в этой последовательности могут быть повторяющиеся члены). Выяснить, сколько чисел входит в последовательность...

Даны целые числа x1, ., xn. Определить количество чисел, входящих в последовательность по одному разу - C++
Помогите,вроде идея есть,но не могу написать правильно Даны целые числа x1, ..., xn. Определить количество чисел, входящих в...

Выяснить, сколько раз в данную последовательность входит группа подряд идущих символов, образующих слово - C++
Выяснить, сколько раз в данную последовательность входит группа подряд идущих символов, образующих слово С++

Для каждого из чисел массива выяснить, сколько раз каждое из них входит в этот массив - C++
Задача Дан массив целых чисел. Для каждого из этих чисел выяснить сколько раз каждое число входит в этот массив. Результат представить в...

Даны натуральное n и целые a1, a2, ., an. Найти сколько чисел входят в последовательность более чем по 1 разу - C++
Нужна помощь в написании задачи с массив. Условие: Даны натуральное n и целые a1, a2, ..., an. Внутри последовательности могут быть...

Сформировать список L включив в него по одному разу элементы, которые входят в один из списков L1 и L2, но в то же время не входит во второй из них - C++
Добрый вечер! Помогите, пожалуйста, начинающей программистке решить следующую задачу: Разработать шаблон класса для работы с...

30
alkagolik
Заблокирован
29.10.2011, 18:30 #2
Glam_Man, суть в том, что ваш массив b[N], статический и сравнивать значения с ним действительно нет смысла, потому что все его элементы - мусор. Надо создать вспомогательный динамический массив (можно и без этого конечно, ведь задача сводится к тому чтобы вывести количество неповторяющихся), добаить в него первый элемент массива a (т.е. a[0]), и дальше в случае необходимости расширять с помощью realloc. Но повторюсь что для выполнения задачи вспомогательный массив не нужен в принципе. Могу переписать покомпактней.

Добавлено через 1 час 25 минут
вот смотрите. я сначала писал на одном массиве, а потом решил добавить вспомогательный массив, просто так . На самом деле он не нужен вовсе.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
 
int double_num(int *arr, const size_t N){
 
    int tmp = 0, flag, *arr_tmp;
 
    arr_tmp = (int*) malloc (sizeof(int));
    if ( !arr_tmp )
        exit ( -1 );
 
    for (int i = 0; i < N; ++i)
    {
        flag = 1;
 
        for (int k = 0; k < N; ++k)
            if( ( arr[ i ] == arr[ k ] ) & ( i != k ) )
            {
                flag = 0;
                break;
            }
 
        if ( flag )
        {
            ++tmp;
 
            arr_tmp = realloc(arr_tmp, tmp * sizeof(int));
            if ( !arr_tmp )
                exit ( -1 );
 
            arr_tmp[ tmp - 1 ] = arr[ i ];
        }
    }
 
    for (int i = 0; i < tmp; ++i)
        printf("%d ", arr_tmp[i]);
    printf("\n");
 
    free(arr_tmp);
    return tmp;
}
 
int main ()
{
    int *arr;
    const size_t N = 20;
    srand(time(0));
 
    arr = (int*)malloc(N * sizeof(int));
    if ( !arr )
        exit ( -1 );
 
    for (int i = 0; i < N; ++i)
    {
        arr[i] = rand() % N;
        printf("%d ", arr[i]);
    }
    printf("\n");
    printf("неповторяющихся элементов %i\n\n", double_num(arr, N));
 
    free(arr);
    return 0;
}
0
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
30.10.2011, 06:45  [ТС] #3
alkagolik
Спасибо за старания, но вы используете много того, чего нам пока что запрещают использовать. То, что можно обойтись одним массивом я уже понял. Не могли бы вы мне ещё пояснить, почему же моя программа всё правильно считает?
0
mimicria
return (true);
1958 / 1095 / 91
Регистрация: 19.04.2011
Сообщений: 2,345
30.10.2011, 06:54 #4
Цитата Сообщение от Glam_Man Посмотреть сообщение
вы используете много того, чего нам пока что запрещают использовать

Не по теме:

Запрещённые функции си, скандалы, интриги, расследования


На самом деле преподаватель прав. Но ваш алгоритм можно (и нужно изменить) так:
у нас в k лежит количество элементов в массиве b, поэтому и сравнения надо делать в цикле не до n, а до k
C++
1
2
                while ((flagNo)&&(j<k))
                {
0
alkagolik
Заблокирован
30.10.2011, 09:44 #5
Цитата Сообщение от mimicria Посмотреть сообщение
у нас в k лежит количество элементов в массиве b, поэтому и сравнения надо делать в цикле не до n, а до k
не выйдет. этот прием гарантирует что мы получим каждое из всех чисел (и те, которые повторяются) только один раз, т.е. перепечатаем все числа, включая повторяющиеся, но без повторов. Надо именно 2 полных прохода по одному циклу (можно с обрывами цикла) чтобы проверить повторное вхождение.
Цитата Сообщение от Glam_Man Посмотреть сообщение
Не могли бы вы мне ещё пояснить, почему же моя программа всё правильно считает?
ну собственно сказал. Сравнивать надо массив с самим собой. Считать вхождения каждого числа (это если тупо). Второй массив сбивает с толку, потому что он не нужен. Правильно вам преподаватель говорит, какой в этом смысл (если это ничего не меняет)? строки 13 - 21 и есть алгоритм поиска.
вот оно же, но с одним статическим массивом. Ничего лишнего, и все просто.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
#include <time.h>
 
int double_num(int *arr, const size_t N){
 
    int tmp = 0, flag;
 
    for (int i = 0; i < N; ++i)
    {
        flag = 1;
 
        for (int k = 0; k < N; ++k)
            if( ( arr[ i ] == arr[ k ] ) & ( i != k ) )
            {
                flag = 0;
                break;
            }
 
        if ( flag )
            ++tmp;
    }
    return tmp;
}
 
int main ()
{
    const size_t N = 20;
    int arr[N];
    srand(time(0));
 
    for (int i = 0; i < N; ++i)
    {
        arr[i] = rand() % N;
        printf("%d ", arr[i]);
    }
    printf("\n");
    printf("неповторяющихся элементов %i\n\n", double_num(arr, N));
 
    return 0;
}
0
mimicria
return (true);
1958 / 1095 / 91
Регистрация: 19.04.2011
Сообщений: 2,345
30.10.2011, 09:58 #6
Цитата Сообщение от alkagolik Посмотреть сообщение
не выйдет. этот прием гарантирует что мы получим каждое из всех чисел (и те, которые повторяются) только один раз, т.е. перепечатаем все числа, включая повторяющиеся, но без повторов. Надо именно 2 полных прохода по одному циклу (можно с обрывами цикла) чтобы проверить повторное вхождение.
Я понял, думал надо просто отбросить повторы Тогда да, сравнивать надо один и тот же массив
Цитата Сообщение от alkagolik Посмотреть сообщение
if( ( arr[ i ] == arr[ k ] ) & ( i != k ) )
&&
0
alkagolik
Заблокирован
30.10.2011, 10:57 #7
Цитата Сообщение от mimicria Посмотреть сообщение
&&
разница? логическое И с множеством {0,1} почему не битовая? ( arr[ i ] == arr[ k ] ) вернет {0, 1} и ( i != k ) вернет {0, 1} так зачем же усложнять.

Добавлено через 12 минут
я точно не знаю, но если подумать логически, то на уровне микросхемы функция x && y возвращает z = фи(x) & фи(y), где фи(альфа) = альфа | альфа с выходом в младший бит (мультиплексирование), в то время как побитовая ограничится только одной векторной бинарной операцией z = x & y. Тоже касается и остальных функций. Попроавьте кто-то если не так.
0
mimicria
return (true);
1958 / 1095 / 91
Регистрация: 19.04.2011
Сообщений: 2,345
30.10.2011, 11:01 #8
Цитата Сообщение от alkagolik Посмотреть сообщение
разница?
Насколько я понимаю, разница в том, что при && второе условие даже не будет рассчитываться, если первое уже ложно
0
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
31.10.2011, 09:01  [ТС] #9
alkagolik
Нам пока что запрещают использовать условный выход break. rand() и запись вида "++<идентификатор счётчика>" также запрещены
0
alkagolik
Заблокирован
31.10.2011, 09:24 #10
Цитата Сообщение от Glam_Man Посмотреть сообщение
Нам пока что запрещают использовать условный выход break. rand() и запись вида "++<идентификатор счётчика>" также запрещены
если вы уберете break, то алгоритм не тработает. надо в этом случае полностью менять подход к решению задачи. Вы точно уверены в том что это имнно ЗАПРЕЩЕНО? Если нет, то можно проявить инициативу (уверен в том, что она будет принята начальником).
Вместо rand() используйте ввод с клавиатуры (не буду же я за вас сидеть и долбить по клаве, верно?)
Непонятно почему запрещено использовать инкремент, но если уж так, то вместо инкремента можете вписать строки типа x = x + 1;

Добавлено через 8 минут
Цитата Сообщение от mimicria Посмотреть сообщение
Насколько я понимаю, разница в том, что при && второе условие даже не будет рассчитываться, если первое уже ложно
сигнал о том - вычислять дальше или нет, тоже должен поступить в результате вычислений... и в данном примере как для битовой операции, так и для "псевдологической" используется одна КС, так что при машинном нуле в первом условии в обоих случаях второе условие не вычисляется, я потому и подчеркнул что имеем дело с множеством {0, 1}, и следовательно лучше использовать именно битовую функцию. в рамках данной задачи разницы нет, но когда речь идет об экономии ресурсов - такая мелочь вполне может "отсеять" миллионы лишних операций.
0
mimicria
return (true);
1958 / 1095 / 91
Регистрация: 19.04.2011
Сообщений: 2,345
31.10.2011, 09:32 #11
Цитата Сообщение от alkagolik Посмотреть сообщение
так что при машинном нуле в первом условии в обоих случаях второе условие не вычисляется
Вычисляется, в этом то и вся разница
0
alkagolik
Заблокирован
31.10.2011, 09:37 #12
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdlib.h>
....
int double_num(int *arr, const size_t N){
 
    int tmp = 0, flag;
 
    for (int i = 0; i < N; ++i)
    {
        flag = 0;
 
        for (int k = 0; k < N; ++k)
            if( ( arr[ i ] == arr[ k ] ) & ( i != k ) )
                flag = flag + 1;
 
        if ( flag == 1 )
            tmp = tmp + 1;
    }
    return tmp;
}
Добавлено через 3 минуты
Цитата Сообщение от mimicria Посмотреть сообщение
Вычисляется, в этом то и вся разница
друг, не убедил. давай по существу. Что вычисляется, как вычисляется, почему именно так...
0
Glam_Man
6 / 6 / 0
Регистрация: 15.10.2011
Сообщений: 73
31.10.2011, 09:38  [ТС] #13
Если заменить "++i" на "i++" в 7 строке, то ничего не изменится?
0
mimicria
return (true);
1958 / 1095 / 91
Регистрация: 19.04.2011
Сообщений: 2,345
31.10.2011, 09:38 #14
Цитата Сообщение от alkagolik Посмотреть сообщение
друг, не убедил. давай по существу. Что вычисляется, как вычисляется, почему именно так...
Простейший тест убедит?
C++
1
2
3
4
5
6
 int test=5, d;
 if(false && test++>10) d=100; // это называется неполное вычисление булевых выражений
 cout << test << endl;
 test=5;
 if(false & test++>10) d=100;
 cout << test << endl;
0
alkagolik
Заблокирован
31.10.2011, 10:05 #15
Цитата Сообщение от Glam_Man Посмотреть сообщение
Если заменить "++i" на "i++" в 7 строке, то ничего не изменится?
нет, не изменится. смотри, "++i" - это ПРЕфиксная запись. В этом случае она имеет наивысший приоритет. т.е. в случае при x = 4; y = ++x; сначала вычисляется x = x + 1, а уже после y = x. в случае же ПОСТфиксиной записи "x++", будет сначала вычислено y = x, а уже после x = x + 1;
Цитата Сообщение от mimicria Посмотреть сообщение
Простейший тест убедит?
нет, не убедил. мнепоказалось что вы не имеете представления о предмете разговора. Вы рассуждаете в аспекте высокоуровневого программирования, в то время как я говорю вам о работе транзисторов. То что человеческий мозг вычисляет и при этом человек не замечает, не распростроняется на технику. Приемнику нужен точный сигнал - вычислять данную КС или ее не вычислять. В рамках данной дискуссии говорю (повторяюсь) что для этой задачи существует одна КС, которая отрабатывается обоими функциями (псевдологическая(последующая из бинарной) "&&" и баниарная "&").
Кроме того вы пытаетесь ввести меня(или себя) в заблуждение лексемами "if false &" "if false &&", что любыми компилятороми преобразуется в нуль.
0
31.10.2011, 10:05
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.10.2011, 10:05
Привет! Вот еще темы с ответами:

Дана последовательность чисел. Выяснить, сколько раз в ней встречается максимальное число - C++
#include &lt;iostream.h&gt; #include &lt;stdlib.h&gt; #include &lt;time.h&gt; #include &lt;stddef.h&gt; // ------------ size_t index_of_max(int* a,...

Дана последовательность чисел. Выяснить , сколько раз в ней встречается максимальное число. - C++
помогите решить задачу для зачета,а то я совсем ничего не понимаю(((( Дана последовательность чисел. Выяснить , сколько раз в ней...

Дана последовательность чисел. Выяснить , сколько раз в ней встречается максимальное число. - C++
Дана последовательность чисел. Выяснить , сколько раз в ней встречается максимальное число.

Выяснить, входит ли в последовательность S1 ,. . ., Sm буква Ю - C++
Даны натуральное число n, символы S1 ,..., Sn . Известно, что символ S1 отличен от символа * и что среди S2 , S3 ,. . ., Sn ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru