Поиск
 
 

Результаты :
 


Rechercher Расширенный поиск

Кто сейчас на форуме
Сейчас посетителей на форуме: 2, из них зарегистрированных: 0, скрытых: 0 и гостей: 2

Нет

[ Посмотреть весь список ]


Больше всего посетителей (7) здесь было Сб Июн 17, 2017 3:57 pm
Самые активные пользователи за неделю


Домашняя работа №12

Предыдущая тема Следующая тема Перейти вниз

Домашняя работа №12

Сообщение автор Gragory023 в Пн Мар 20, 2017 12:21 pm

Первую программу сделал, получилось вот так
Код:
#include <iostream>
#include <time.h>
#include <iomanip>
#include <stdlib.h>

using namespace std;

void randmizeArray(int *a, int size) {
 for (int i = 0; i < size; i++, a++)
 *a = rand() % 120;
}
void printArray(const int *a, int  size) {
 for (int i = 0; i < size; i++, a++)
 cout << *a << ' ';
 cout << endl;
}
void swap(int *px, int *py) {
 int temp = *px;
 *px = *py;
 *py = temp;
}


void change(int *a, int size) {
 for (int i = 0; i < size; i++, a++)
 if (i % 2 != 0)
 swap(a, a-1);
}


int main() {
 const int SIZE = 10;
 int a[SIZE];
 srand(unsigned(time(0)));
 randmizeArray(a, SIZE);
 printArray(a, SIZE);
 change(a, SIZE);
 printArray(a, SIZE);
}

Со второй немного возникли трудности.
Первая проблема, в том что не получается ввести массивы с клавиатуры, возможно где то делаю ошибку.
Вторая не получается перенести первые два миссива в третий(
Так же не понял, пользователь вводит два массива, упорядоченных по возрастанию: a[N] и b[M].
Это значит он должен вводить заранее упорядоченный, или после ввода происходит упорядочивание?
Если так, то следующий вопрос возникает, зачем их упорядочивать, если можно значения перезаписать в третий массив и потом уже упорядочить?
Код:
void creat_array(int *a, int *b, int *c,int size) {
 for (int i = 0; i < size * 2; i++) {
 for (int j = 0; j < size; j++) {
 c[i] = a[j];
 
 }
 for (int j = 0; j < size; j++) {
 int temp = a[j];
 c[i] = a[j] ;
 }
 }
}
void randmizeArray(int *a, int size) {//пока попробовал рандомно заполнить
 for (int i = 0; i < size; i++, a++)
 *a = rand() % 120;

}
void printArray(const int *a, int  size) {
 for (int i = 0; i < size; i++, a++)
 cout << *a << ' ';
 cout << endl;
}
int main() {
 const int SIZE = 5;
 int a[SIZE], b[SIZE], c[SIZE*2];
 randmizeArray(a, SIZE);
 randmizeArray(b, SIZE);
 /*cout << "Enter first array" << endl;
 for (int i = 0; i < SIZE; i++)
 cin >> a[SIZE];
 cout << "Enter second  array" << endl;*/
 
 printArray(a, SIZE);
 printArray(b, SIZE);
 creat_array(a, b, c, SIZE);
 printArray(c, SIZE*2);
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Пн Мар 20, 2017 2:03 pm

1+ Отлично

Так же, как мы наполняем массив случайными числами:
Код:
*a = rand () % 120;
Можно вводить их с клавиатуры:
Код:
cin >> *a;

Вообще в формулировке задачи пользователь вводит уже отсортированный массив. Можно, например, проверить программой, что он отсортирован; или насильно отсортировать его после ввода.

Предполагалось, что размеры массива a и b могут быть разными: N и M. Например, один массив из 5 чисел, а другой из 10.

Соединение массивов сейчас не работает, потому что есть только операция вида
Код:
c[i] = a[j];
в то время как массив b вообще не используется.

Идея отсортированных массивов, которые мы потом соединяем в один отсортированный массив — это алгоритм сортировки слиянием. Напомню:



• У нас есть читающая позиция для массивов a и b. Она двигается слева направо в каждом массиве.
• Помимо этого, у нас есть записывающая позиция в массиве c. Она тоже двигается слева направо.
• На каждом шаге мы сравниваем числа, записанные в a и b. Меньшее из двух числе «побеждает»: его записываем в c.
• После чего надо сдвинуть «победившую» читающую позицию на один вправо. Например, если «победил» элемент из a, то a сдвигаем вправо на 1; b остаётся на месте.
• c сдвигаем вправо в любом случае.

Если a и b были отсортированы по возрастанию, то результирующий массив тоже будет отсортирован по возрастанию.
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Пн Мар 20, 2017 3:05 pm

Почему победившую» читающую позицию на один вправо, вроде наоборот проигравшую.

Сейчас написал так, но опять не работает(
Код:

void creat_array(int *a, int *b, int *c, int size) {
   for (int i = 0; i < size * 2; i++) {
      for (int j = 0; j < size; j++) {
         if (a[j] < b[j]) {
            c[i] = a[j];
            c[i + 1] = b[j];
         }
         else
            c[i] = b[j];
         c[i + 1] = a[j];

      }
   }
}

и не понял почему не работает соединение, сейчас использую и a и b
Код:
void creat_array(int *a, int *b, int *c,int size) {
 for (int i = 0; i < size * 2; i++) {
 for (int j = 0; j < size; j++) {
 c[i] = a[j]; - вот первый массив
 
 }
 for (int j = 0; j < size; j++) {
 int temp = a[j];
 c[i] = b[j] ;
 }
 }
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Пн Мар 20, 2017 3:30 pm

По поводу второго фрагмента кода — всё просто: мы записываем оба массива на одно и то место:
Код:
c[i] = a[j];
c[i] = b[j];
а хотелось бы один после другого. К тому же переписывание массива — это не цикл в цикле; достаточно одного for.

По поводу слияния массивов. Нужно две независимые переменные; позиция в массиве a может изменяться незаивисимо от позиции в массиве b. (То есть a[j] < b[j] — неправильно, так позиции в a и b всё время одинаковые).

Смысл слияния в том, что мы ищем наименьший элемент в a и b; и ставим его в c. После того, как мы перенесли наименьший элемент из a, больше его учитывать не надо. Поэтому в a смещаемся дальше. При этом элемент из b не переносится в c:



Позиция в b осталась прежней, для сравнения с новым a. По сути, мы повторяем эти сравнения в цикле while. Может сместиться либо a, либо b — другая позиция остаётся на месте для последующих сравнений.
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Вт Мар 21, 2017 10:46 am

Не понимаю(
Код:
for (int i = 0; i < size; i++) {
 while (i<size)
 if (a[i] < b[0])// вот идет сравнение
 c[i] = a[i];// записывается
 else
 c[i] = b[i];// если сравнение обратное (но тут знаю, что косяк какой то)
 
 }
Как мы можем брать два миссива например из 5 элементов и записать в третий уже из 10, при этом не используя цикл в цикле?

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Вт Мар 21, 2017 2:04 pm

Отдельные управляющие переменные, отслеживающие позицию в каждом массиве:

Код:
int i = 0; // позиция в a
int j = 0; // позиция в b
int k = 0; // позиция в c

while (k < size) {
}
Там будут использоваться в какой-то комбинации: a[i], b[j], c[k], i++, j++, k++.
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Вт Мар 21, 2017 2:15 pm

Те туда надо вставить два цикла for с сравнением?

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Вт Мар 21, 2017 2:26 pm

Вообщем не знаю(
Код:
void creat_array(int *a, int *b, int *c, int size) {
   int i = 0, j = 0, k = 0;
   while (k < size * 2)
      if (a[i] < b[j]) {
         a[i] = c[k];
         j--;
      }
      else
         b[i] = c[k];
   i++; b++; k++;
   
      
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Вт Мар 21, 2017 3:59 pm

Базовый план в алгоритме слияния такой:

Код:
int i = 0, j = 0, k = 0;
while (k < size * 2) {
  if (a[i] < b[j]) {
      c[k] = a[i]; // копируем a -> c
      k++; i++; // сдвигаемся в a, c
  }
  else {
      c[k] = b[j]; // копируем b -> c
      k++; j++; // сдвигаемся в b, c
  }
}

Однако это ещё не всё. У нас может произойти такая ситуация, что один из массивов a или b уже закончился, а другой нет. Этот случай тоже надо предусмотреть, потому что в таком случае сравнивать a[i] и b[j] нелегально (i или j за пределами массива).

Такую проверку, как правило, добавляют перед сравнением a[i] < b[j], чтобы исключить возможность ошибочного доступа к памяти.

Код:
int i = 0, j = 0, k = 0;
while (k < size * 2) {
  if (i за пределами первого массива)
      тогда нужно не думая копировать очередной элемент из b
  if (j за пределами второго массива)
      тогда нужно не думая копировать очередной элемент из a
  // также если один из этих случаев приключился, надо чтобы этот код не выполнялся:
  if (a[i] < b[j]) {
      c[k] = a[i]; // копируем a -> c
      k++; i++; // сдвигаемся в a, c
  }
  else {
      c[k] = b[j]; // копируем b -> c
      k++; j++; // сдвигаемся в b, c
  }
}
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Ср Мар 22, 2017 12:47 pm

Сделал так, но третий массив не печатает(
Код:
void creat_array(int *a, int *b, int *c, int size) {
 int i = 0, j = 0, k = 0;
 while (k < size * 2)
 if (i==size)
 c[k] = b[j];
 else if (j==size)
 c[k] = a[i];
 else {
 if (a[i] < b[j]) {
 c[k] = a[i];
 k++; j++;
 }
 else {
 c[k] = b[i];
 k++; j++;
 }
 }
 
}
 void enterArray(int *a, int size) {
 for (int i = 0; i < size; i++, a++)
 cin >> *a;
 }
 void printArray(const int *a, int  size) {
 for (int i = 0; i < size; i++, a++)
 cout << *a << ' ';
 cout << endl;
}
 int main() {
 const int SIZE = 5;
 int a[SIZE], b[SIZE], c[SIZE * 2];
 enterArray(a, SIZE);
 enterArray(b, SIZE);
 printArray(a, SIZE);
 printArray(b, SIZE);
 creat_array(a, b, c, SIZE);
 printArray(c, SIZE * 2);
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Ср Мар 22, 2017 2:31 pm

С третьем тоже немного не понятно;
Вообще правильно делаю?
Код:
void creat_array(int *a, int *b, int *c, int size) {
   int i = 0, j = 0, k = 0;
   while (k < size * 2) {
      if (i < size) {
         c[k] = a[i];
         i++; k++;
      }
      else {
         c[k] = b[j];
         j++; k++;
      }
   }
}
void сommon_elements(int *a, int *b,  int size) {
   for (int i = 0; i < size; i++)
      for (int j = 0; j < size; j++)
         if (a[i] == b[j] && i != j)
            cout << a[i] << ' ';
   cout << endl;
}
void a_not_include_b(int *a, int *b, int size) {
   for (int i = 0; i < size; i++)
      for (int j = 0; j < size; j++)
         if (a[i] != b[j] && i != j) {
            cout << a[i] << ' ';
            break;
         }
   cout << endl;
}
void randmizeArray(int *a, int size) {
   for (int i = 0; i < size; i++, a++)
      *a = rand() % 12;

}
void printArray(const int *a, int  size) {
   for (int i = 0; i < size; i++, a++)
      cout << *a << ' ';
   cout << endl;
}
int main() {
   srand(time(NULL));
   const int SIZE = 5;
   int a[SIZE], b[SIZE], c[SIZE * 2], size_common, size_common_array[SIZE];
   randmizeArray(a, SIZE);
   randmizeArray(b, SIZE);
   printArray(a, SIZE);
   printArray(b, SIZE);
   creat_array(a, b, c, SIZE);
   printArray(c, SIZE * 2);
   сommon_elements(a, b,  SIZE);
   a_not_include_b(a, b, SIZE);
   
}
Почему то печатаются все элементы, при условии печатать только элементы а не входящие в б?

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Ср Мар 22, 2017 4:49 pm

Код:
if (i==size)
  c[k] = b[j];
else if (j==size)
  c[k] = a[i];
Этого мало. Помимо копирования элемента нужно ещё продвинуться вперёд в соответствующих массивах. Иначе зациклится.
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Ср Мар 22, 2017 5:00 pm

С третьей подход неудачный. В common_elements каждый элемент будет напечатан дважды: сначала для i, j, а потом для j, i. А без break ещё больше раз.

В a_not_include_b этот подход вообще не работает.

На самом деле нужно для каждого a[i] ответить на вопрос: такой элемент входит в b или нет? Ответить на этот вопрос можно либо отдельной функцией, выполняющей поиск элемента по массиву b, либо циклом с накопляющей переменной типа bool:
Код:
bool b_contains_a_i = false;
for j
   if (b[j] == a[i])
      b_contains_a_i = true;
По окончании цикла можно проанализировать переменную b_contains_a_i и принять решение, включать такой элемент или нет.
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Чт Мар 23, 2017 10:12 am

Второе задание вот так получилось. Единственное не понял, как сделать, чтобы длина массива была разная, и задавалась пользователем?
Код:
void creat_array(int *a, int *b, int *c, int size) {
   int i = 0, j = 0, k = 0;
   while (k < size * 2)
      if (i == size) {
         c[k] = b[j];
         k++; j++;
      }
      else if (j == size) {
         c[k] = a[i];
         k++; i++;
      }
      else {
         if (a[i] < b[j]) {
            c[k] = a[i];
            k++; i++;
         }
         else {
            c[k] = b[j];
            k++; j++;
         }
      }
}

inline void swap(int a[], int i, int j) {
   int temp = a[i];
   a[i] = a[j];
   a[j] = temp;
}

void selectionSpot(int a[], int n) {
   for (int i = 0; i < n; i++) {
      int minPlace = i;
      for (int j = i; j < n; j++)
         if (a[j] < a[minPlace])
            minPlace = j;
      swap(a, i, minPlace);
   }
}

   void enterArray(int *a, int size) {
      for (int i = 0; i < size; i++, a++)
         cin >> *a;
   }
   void printArray(const int *a, int  size) {
   for (int i = 0; i < size; i++, a++)
      cout << *a << ' ';
   cout << endl;
}

   int main() {
      const int SIZE = 5;
      int a[SIZE], b[SIZE], c[SIZE * 2];
      enterArray(a, SIZE);
      selectionSpot(a, SIZE);
      enterArray(b, SIZE);
      selectionSpot(b, SIZE);
      printArray(a, SIZE);
      printArray(b, SIZE);
      creat_array(a, b, c, SIZE);
      printArray(c, SIZE * 2);
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Чт Мар 23, 2017 10:15 am

По третьей, как я понимаю общие элементы массива печатать тоже используя накопительную переменную типа bool, но что то не могу разобрать до конца, как это делать в функции?
Вот так написал, но печатает все элементы массива b(((
Код:
void a_not_include_b(int *a, int *b, int size) {
   bool b_contains_a_i = false;
   for (int i = 0; i < size; i++) {
      for (int j = 0; j < size; j++)
         if (b[j] == a[i])
            b_contains_a_i = true;
   }
   for (int j = 0; j < size; j++)
      if (b_contains_a_i = true)
         cout << b[j];
         cout<<endl;
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Чт Мар 23, 2017 4:02 pm

По второй. Длина массива не может задаваться пользователем, т. к. должна быть предопределённой константой на этапе компиляции. Но она может быть разной:
Код:
int N = 5;
int M = 10;
int a[N], b[M], c[N + M];
Я взял числа с потолка, лишь бы были разными.

По третьей. Присваивание в if — плохая идея
Код:
if (b_contains_a_i = true)

На самом деле все операции должны были быть внутри цикла по i:
Код:
для каждого i {
   выясним, содержится ли a[i] в b
   для этого заведём переменную bool «содержится» = false
   переберём все b[j], и если найдём равную, сделаем «содержится» = true
   если «содержится», то такой a[i] печатать надо.
}
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Пт Мар 24, 2017 10:13 am

Так и делаю:
Код:
void a_not_include_b(int *a, int *b, int size) {
   bool b_contains_a_i = false;//pfdjlbv gthtvtyye.
   for (int i = 0; i < size; i++) {
      for (int j = 0; j < size; j++)
         if (a[i] == b[j])//перебираем и ищем равную
            b_contains_a_i = true;
      if (b_contains_a_i = false)//если фолс, то печатаем
         cout << a[i];
   }
}

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Пт Мар 24, 2017 9:04 pm

Разница есть, переменная b_contains_a_i объявлена и присвоена false до цикла (единственный раз), или внутри цилка (для каждого i).

Какой вариант верный?
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Сб Мар 25, 2017 6:51 pm

Вот так сделал, но все равно не всегда правильно показывает и повторяющиеся числа и не включающиеся в другой массив(((
Код:
void creat_array(int *a, int *b, int *c, int size) {
   int i = 0, j = 0, k = 0;
   while (k < size * 2) {
      if (i < size) {
         c[k] = a[i];
         i++; k++;
      }
      else {
         c[k] = b[j];
         j++; k++;
      }
   }
}

void сommon_elements(int *a, int *b, int size) {
   for (int i = 0; i < size; i++) {
      bool b_contains_a_i = false;
      for (int j = 0; j < size; j++)
         if (a[i] == b[j])
            b_contains_a_i = true;
      if (b_contains_a_i == true)
         cout << a[i] << ' ';
   }
   cout << endl;
}



void not_include(int *a, int *b, int size) {
  for (int i = 0; i < size; i++) {
      bool b_contains_a_i = false;
      for (int j = 0; j < size; j++)
        if (b[j] == a[i])
            b_contains_a_i = true;
      if (b_contains_a_i == false)
        cout << b[i] << ' ';
  }
  cout << endl;
}
void not_include_all(int *a, int *b, int size) {
 for (int i = 0; i < size; i++) {
 bool b_contains_a_i = false;
 for (int j = 0; j < size; j++)
 if (b[j] == a[i])
 b_contains_a_i = true;
 if (b_contains_a_i == false)
 cout << b[i] << ' ';
 }
}

void randmizeArray(int *a, int size) {
 for (int i = 0; i < size; i++, a++)
 *a = rand() % 12;

}
void printArray(const int *a, int  size) {
 for (int i = 0; i < size; i++, a++)
 cout << *a << ' ';
 cout << endl;
}
int main() {
 srand(time(NULL));
 const int SIZE = 5;
 int a[SIZE], b[SIZE], c[SIZE * 2], size_common, size_common_array[SIZE];
 randmizeArray(a, SIZE);
 randmizeArray(b, SIZE);
 printArray(a, SIZE);
 printArray(b, SIZE);
 creat_array(a, b, c, SIZE);
 printArray(c, SIZE * 2);
 сommon_elements(a, b, SIZE);
 not_include(a, b, SIZE);
 not_include(b, a, SIZE);
 not_include_all(a, b, SIZE);
 not_include_all(b, a, SIZE);
 cout << endl;
}
Что не правильно делаю?(

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Ярослав в Сб Мар 25, 2017 8:42 pm

С виду не понять... надо под отладчиком внимательнее посмотреть. На каких массивах косячит?
avatar
Ярослав
Admin

Posts : 346
Join date : 2016-12-21
Location : Москва

Посмотреть профиль http://itstep.forum2x2.ru

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Gragory023 в Вс Мар 26, 2017 12:16 am

Работает странно, иногда все находит, иногда находит не все числа не входящие в другой массив.

Gragory023

Posts : 75
Join date : 2016-12-28

Посмотреть профиль

Вернуться к началу Перейти вниз

Re: Домашняя работа №12

Сообщение автор Спонсируемый контент


Спонсируемый контент


Вернуться к началу Перейти вниз

Предыдущая тема Следующая тема Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения