Как найти подряд идущие элементы

aus

7 / 7 / 3

Регистрация: 18.10.2010

Сообщений: 56

1

Найти в массиве подряд идущие элементы

18.10.2010, 14:06. Показов 2993. Ответов 12

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

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
//---------------------------------------------------------------------------
 
#include <vcl.h>
#pragma hdrstop
#include <iostream.h>
#include <conio.h>
#include <stdio.h>
//---------------------------------------------------------------------------
 
#pragma argsused
int main(int argc, char* argv[])
{       int n; int S=0;
        int *parr;
        cout<<"Vvedite razmer massiva:";
        cin>>n;
        parr=new int[n];
        for (int i=0;i<n;i++)
        {
        cout<<"nVvedite element massiva:";
        cin>>parr[n];
        }
        for (int i=0;i<n;i++)
        {
        if (parr[n]==parr[n+1]) S++;
        }
        cout<<S;
        delete [n] parr;
        getch();
        return 0;
}
//---------------------------------------------------------------------------

Надо найти подряд идущие одинаковые элементы. В чем здесь ошибка?



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

18.10.2010, 14:06

Ответы с готовыми решениями:

Исключить все повторяющиеся, идущие подряд элементы дека
Создать список из целых чисел. Подсчитать количество пар соседних элементов, которые совпадают…

В массиве A=(a1, а2, ., an) удалить все положительные элементы, имеющие четный порядковый номер, идущие после минимального элемента массива
В массиве A=(a1, а2, …, an) удалить все положительные элементы, имеющие четный порядковый номер,…

Идущие подряд числа
Есть код, суть его в возведении числа в степень (ооочень большую степень – 3^3456), в результате…

Заменить в строке пробелы идущие подряд
В заданной строке,заменить парное количество пробелов,которые идут подряд на ‘П’,а не парное на…

12

2923 / 844 / 324

Регистрация: 30.04.2009

Сообщений: 2,633

18.10.2010, 14:11

2

Цитата
Сообщение от aus
Посмотреть сообщение

Надо найти подряд идущие одинаковые элементы. В чем здесь ошибка?

может быть нужно найти самую длинную последовательность одинаковых подряд идущих элементов?

Добавлено через 1 минуту
во вторых в цикле поиска равных нужно делать i<n-1 так как у вас идет сравнение с последующим, а с чем вы будете сравнивать последний элемент, значит нужно последним сравнивать предпоследний элемент



1



7 / 7 / 3

Регистрация: 18.10.2010

Сообщений: 56

18.10.2010, 14:11

 [ТС]

3

Да самую длинную



0



Nevecap

12 / 12 / 4

Регистрация: 18.10.2010

Сообщений: 59

18.10.2010, 14:15

4

C++
1
if (parr[n]==parr[n+1]) S++;

Я так понимаю, в виду имелось

C++
1
if (parr[i]==parr[i+1]) S++;

?)

C++
1
cin>>parr[n];

И здесь тоже…



1



mamedovvms

2923 / 844 / 324

Регистрация: 30.04.2009

Сообщений: 2,633

18.10.2010, 14:18

5

вот этот цикл

C++
1
2
3
4
for (int i=0;i<n;i++)
        {
        if (parr[n]==parr[n+1]) S++;
        }

Замените на это

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
s=1;
 int tempS=1;
int index =0;
for (int i=0;i<n-1;i++){
 if (a[i]==a[i+1]){
  tempS++;
 }
 else{
  if (tempS>s){s=tempS; index=i-s;}
  tempS=1;
 }
}
//Вывод последовательности
for (int i=index; i<index+s;i++){
 cout<<a[i]<<" ";
}



1



7 / 7 / 3

Регистрация: 18.10.2010

Сообщений: 56

18.10.2010, 14:24

 [ТС]

6

Спасиб всем.
И еще он на выделение памяти ошибку выдает



0



2923 / 844 / 324

Регистрация: 30.04.2009

Сообщений: 2,633

18.10.2010, 14:29

7

где выдает?



0



7 / 7 / 3

Регистрация: 18.10.2010

Сообщений: 56

18.10.2010, 14:35

 [ТС]

8

На освобождении памяти



0



В астрале

Эксперт С++

8048 / 4805 / 655

Регистрация: 24.06.2010

Сообщений: 10,562

18.10.2010, 14:40

9

aus, Угу. Потому что просто delete[] parr;



1



Shman

6 / 6 / 6

Регистрация: 30.04.2012

Сообщений: 216

25.05.2012, 17:34

10

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
#include <stdio.h> // Подключаем
#include <conio.h> // модули.
 
int main()
{     
 int mass[5]; // Обявляем массив.
 int i, n, s, tempS, index; // Переменные.
 
 printf("Vvedite massiv iz 5 elementov n:"); 
 
  for (i=0; i<5; i++) // Счетчик.
   { printf("Vvedite element[%d]: ", i); // Введите очередной элемент массива.
     scanf("%d", &mass[i]); } // Запомнить ввод.
 
 s=1;
 tempS=1;
 index=0;
  for (i=0; i<i-1; i++){
   if (mass[i]==mass[i+1])
    { tempS++; }
   else
    {
      if (tempS>s)
      { s=tempS; 
        index=i-s; }
     tempS=1;
    }
   
  for (i=index; i<index+s; i++)  
  {
    printf ("n Result: %d ", mass[i]); // Вывести результат. 
  }
 getch(); 
 return 0;
}
}

ГДЕ ОШИБКА скажите пжста?



0



Nevecap

12 / 12 / 4

Регистрация: 18.10.2010

Сообщений: 59

25.05.2012, 23:41

11

Цитата
Сообщение от Shman
Посмотреть сообщение

[CPP]
ГДЕ ОШИБКА скажите пжста?

Во-первых, в цикле

C
1
for (i=0; i<i-1; i++)

условие i < i-1 всегда ложно.
UPD Блин, старая версия прогрузилась…
UPD2 А, не, уже исправлено просто, трудный день был, не сразу понял)



0



MrGluck

Форумчанин

Эксперт CЭксперт С++

8194 / 5044 / 1437

Регистрация: 29.11.2010

Сообщений: 13,453

26.05.2012, 03:36

12

Цитата
Сообщение от Shman
Посмотреть сообщение

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
#include <stdio.h> // Подключаем
#include <conio.h> // модули.
 
int main()
{     
 int mass[5]; // Обявляем массив.
 int i, n, s, tempS, index; // Переменные.
 
 printf("Vvedite massiv iz 5 elementov n:"); 
 
  for (i=0; i<5; i++) // Счетчик.
   { printf("Vvedite element[%d]: ", i); // Введите очередной элемент массива.
     scanf("%d", &mass[i]); } // Запомнить ввод.
 
 s=1;
 tempS=1;
 index=0;
  for (i=0; i<i-1; i++){
   if (mass[i]==mass[i+1])
    { tempS++; }
   else
    {
      if (tempS>s)
      { s=tempS; 
        index=i-s; }
     tempS=1;
    }
   
  for (i=index; i<index+s; i++)  
  {
    printf ("n Result: %d ", mass[i]); // Вывести результат. 
  }
 getch(); 
 return 0;
}
}

ГДЕ ОШИБКА скажите пжста?

в этом интересном условии цикла

C++
1
for (i=0; i<i-1; i++){

Один вопрос, почему vcl.h ?



0



6 / 6 / 6

Регистрация: 30.04.2012

Сообщений: 216

26.05.2012, 06:18

13

Nevecap,
MrGluck,

В этом интересном условии цикла

А как правильно?



0



Как найти подряд идущие значения в массиве?

есть массив такого вида

const arr = [
'значение 1',
'значение 3', 
'значение 1', 
'значение 2', 
'значение 1', 
'значение 4', 
'значение 1', 
'значение 6',
'значение 1', 
'значение 2']

Как найти подряд идущие заданные значения? К примеру мне нужно найти сколько раз попадалось в массиве значение 1 и сразу за ним было значение 2


  • Вопрос задан

    более двух лет назад

  • 948 просмотров

С помощью цикла.
Не знаю, почему в моду вошло написание решений в одну строчку в функциональном стиле, словно это быстрее работает или проще понять при прочтении.

let cnt = 0; //число совпадений
for(let i = arr.length-1; i > 0; i--) {
  if (arr[i] == 'значение 2' && arr[i-1] == 'значение 1') cnt++;
}

arr.reduce( (acc,v,i,a)=> i > 0 && v === 'значение 2' && a[i-1] === 'значение 1' ? acc + 1 : acc, 0)

Пригласить эксперта


  • Показать ещё
    Загружается…

17 мая 2023, в 15:05

10000 руб./за проект

17 мая 2023, в 15:00

25000 руб./за проект

17 мая 2023, в 14:49

25000 руб./за проект

Минуточку внимания

aus



Гуру

(3991),
закрыт



12 лет назад

Лучший ответ

I Am Dubbed

Просветленный

(20880)


12 лет назад

если на примитивном уровне
for(int k =0;k<arraySize-1;k++){
if ( a[k] == a[k+1] )
cout << “Same element at ” << k << ” and ” << k + 1 << endl;
}

Остальные ответы

преданный

Мыслитель

(7278)


12 лет назад

сравнивать n-1 c nnым с помощью if then else

Похожие вопросы

//gcc 5.4.0
 
#include  <stdio.h></stdio.h>
 
 
int *skip_equals(int *begin, int *end)
{
    if (begin != end) {
        int val = *(begin++);
        while (begin != end && *begin == val) {
            ++begin;
        }
    }
    return begin;
}
 
void output_length_seqs(int *begin, size_t size)
{
    int *end = begin + size;
    while (begin != end) {
        int *end_cur_seq = skip_equals(begin, end);
        size_t length = end_cur_seq - begin;
        printf("%d - %zun", *begin, length);
        begin = end_cur_seq;
    }
}
 
 
int main(void)
{
    int array[] = {1, 5, 3, 4, 4, 5, 5, 5, 2, 2, 1, 1, 3};
    output_length_seqs(array, sizeof(array)/sizeof(*array));
    return 0;
}

Материал из Algocode wiki

Перейти к: навигация, поиск

В этой статье будет разобрана идея бинарного(двоичного) поиска на примере нескольких классических задач.

Содержание

  • 1 Основная идея
  • 2 Задачи
    • 2.1 Поиск первой единицы в массиве
    • 2.2 Поиск элемента в отсортированном массиве
  • 3 Асимптотика
  • 4 Бинарный поиск по неотсортированному массиву
  • 5 Задания

Основная идея

Допустим, у нас есть массив элементов и некоторая функция, которая по элементу возвращает либо True, либо False. Наложим на эту функцию условие – пусть сначала для всех элементов она возвращает True, а потом, начиная с какой-то позиции, возвращает только False. Иными словами, мы хотим работать с монотонной функцией. Проверим любой элемент, спросив значение функции от него. Если это True, то мы знаем, что все элементы левее него тоже будут давать такое значение. Аналогично с False, только мы получим информацию про элементы, которые правее нас.

Мы хотим найти позицию, где заканчивается True и начинается False. Заведем границы поиска – два указателя left и right. Будем поддерживать следующий инвариант: точка перехода лежит где-то на отрезке [left, right], значение в left всегда True, а в right всегда False. Будем проверять значение в середине текущего отрезка middle и сдвигать одну из границ поиска.

Если $F(middle) = False$, то сдвинем правую границу: $right = middle$. Иначе сдвинем левую $left=middle$. Заметим, что инвариант при этом продолжает выполняться.

Выбор границ бинарного поиска

Что делать, если функцию всегда истинна или всегда ложна на данном массиве? Нам необходимо поддерживать описанный выше инвариант. Будем считать, что в массиве есть фиктивные элементы перед самым первым элементом и после последнего элемента и скажем, что $F(-1) = True$, $F(n) = False$. Границы поиска изначально будут равны $left = -1$, $right = n$ (нумерация с нуля).

Перейдем от общих слов к примерам.

Задачи

Поиск первой единицы в массиве

У вас есть массив, состоящий из некоторого количества подряд идущих нулей, за которыми следует какое-то количество подряд идущих единиц. Вам нужно найти позицию первой единицы, то есть найти такое место, где заканчиваются нули, и начинаются единицы. Это можно сделать с помощью линейного поиска за один проход по массиву, но хочется сделать это быстрее с помощью бинарного поиска.
Посмотрим на элемент посередине массива. Если это нуль, то первую единицу стоит искать в правой половине массива, а если единица – то в левой. Решение этой задачи выглядит примерно так:

 1 int left = -1;
 2 int right = n;
 3 while (right - left > 1) {
 4     int middle = (left + right) / 2; //   формула среднего индекса
 5     if (a[middle] == 1) {
 6         right = middle; // right будет указывать на 1
 7     } else {
 8         left = middle; // left будет указывать на 0
 9     }
10 }

Поиск элемента в отсортированном массиве

Ведущий загадал число X от 1 до 100. Вы можете спросить, больше ли мое число чем число T, ведущий отвечает “да” или “нет”. За сколько вопросов в худшем случае вы сможете найти число X? Как нужно действовать?

Для решения используем ту же идею. В самом начале мы говорили о некоторой логической функции $F$, тут она определена достаточно четко.

$
F(a) = left{ begin{array}{c}
True, a < x \
False, a ge x\
end{array}
right.
$

По сути код предыдущего решения отличается лишь строкой 5, где вместо проверки a[middle] == 1 будет стоять a[middle] >= x.

В конце программы указатель $left$ будет стоять на последнем элементе, который меньше $X$, а $right$ – на первом элементе, который больше или равен $X$. Тогда проверим элемент $right$. Если он равен $X$, то $X$ есть в массиве, иначе – нет.

Асимптотика

Почему нужно делить обязательно пополам? Почему бы не спросить “число X больше, чем 80?” первым же вопросом? Но если вдруг ответ “нет”, то мы останемся с 80 вариантами вместо 100. То есть деление отрезка ровно пополам гарантирует, что в худшем случае мы останемся не более чем с половиной вариантов.

Так как отрезок поиска каждый раз уменьшается в два раза, то цикл while выполнится $O(log n)$ раз, где $log n$ – логарифм числа $n$.

Бинарный поиск по неотсортированному массиву

Переформулируем исходную задачу – теперь мы хотим просто найти пару соседних индексов, для одного из которых условие $P$ выполняется, а для другого нет. Здесь уже не требуется упорядоченность всего массива. По принципу непрерывности если для $L$ условие выполнялось, а для $R$ не выполнялось, то где-то между $L$ и $R$ найдется искомая позиция. Опять рассмотрим средний элемент $M$. Перейдем в одну из половин так, чтобы инваиант $P(L) neq P(R)$ выполнялся.

Например, если мы знаем, что $f(x_0) < 0$ и $f(x_1) > 0$, и функция непрерывная, то бинарным поиском можно найти ноль этой функции между $x_0$ и $x_1$, даже если функция не монотонная!

Или, например, если нужно в массиве найти соседние четное и нечетное числа, и известно положение какого-то четного числа и какого-то нечетного числа, то это тоже можно легко сделать с помощью бинарного поиска.

Задания

  1. Какими будут границы $left$ и $right$ на массиве arr = {1, 3, 4, 10, 10, 10, 11, 80, 80, 81} для:
    1. $x = 1$
    2. $x = 10$
    3. $x = 20$
    4. $x = 79$
    5. $x = 80$
    6. $x = 5$
    7. $x = 81$
  2. Придумайте, как с помощью бинарного поиска решить такие задачи:
    1. Найти **первое** число, равное X в отсортированном массиве, или вывести, что таких чисел нет
    2. Найти **последнее** число, равное X в отсортированном массиве, или вывести, что таких чисел нет
    3. Посчитать, сколько раз встречается число X в отсортированном массиве (в решении помогают два предыдущих пункта)
    4. Дан массив чисел, первая часть состоит из нечетных чисел, а вторая – из четных. Найти индекс, начиная с которого все числа четные.

Замечание
Все эти задачи решаются бинарным поиском за $O(log{n})$. Правда нужно понимать, что в чистом виде такую задачу решать двоичным поиском бессмысленно – ведь чтобы создать массив размера $n$, уже необходимо потратить $O(n)$ операций.

Поэтому зачастую такие задачи сформулированы таким образом:

Дан отсортированный массив размера $n$. Нужно ответить на $m$ запросов вида “встречается ли число $x_i$ в массиве n?”

Такая задача целиком решается за $O(n + mlog n)$


Автор конспекта: Полина Романченко

По всем вопросам пишите в telegram @Romanchenko

Добавить комментарий