Тема: Два масиви цілих чисел.

Допоможіть із завданням, будь ласка.
Задано два масиви цілих чисел. Вилучити з першого масиву всі елементи, які
входять до складу другого масиву. Надрукувати перший масив після
скорочення і вказати, скільки елементів вилучено. Підказка: для вилучення
зсувати всі наступні елементи масиву ліворуч.
Поясніть, будь ласка, як зсунути елементи масиву ліворуч, щоб вилучити число?
Якщо можете, з наочним кодом.
Дякую)

2

Re: Два масиви цілих чисел.

Просто в циклі i+1 елемент копіюємо на місце i-го. Якщо треба вилучити 3-й, то 4-й - на місце 3-го, 5-й - на місце 4-го і т.д. І треба пам'ятати, що елементів стало менше, тобто останній елемент масиву тепер не враховується.

Подякували: litovskaolena1

3

Re: Два масиви цілих чисел.

Підкажіть, будь ласка, як виконати здвиг вліво за допомогою вказівників?
Тут  *(А + q) не зчитується як A[q].

#include <stdio.h>
#include <stdlib.h>
#define kMax 5
int main()
{
    long A[kMax], B[kMax];
    long *a, *a2, *b;
    int m, i, k;
    system("chcp 1251");
    printf("Введіть цілі числа( їхня кількість має бути < %d ) масиву А:\n", kMax);
    k = 0;
    do {
        scanf_s("%ld", A + k);
        if (*(A + k) == 0)
            break;
    } while (++k < kMax);
    printf("Введіть цілі числа( їхня кількість має бути < %d ) масиву В:\n", kMax);
    i = 0; m = 0;
    int q;
    do {
        b = (B + i);
        scanf_s("%ld", b);

        if (*b == 0) 
            break;
        for (m = 0; m < k; m++) {
            a = (A + m);
            if (*a == *b) {
                for ( q=0; q < k; q++) {
                   
                                        *(A + q) = *(A + ++q);
                    
                                          continue;
                }
            }
        }
        
        
    } while (++i < kMax);
    for (int o = 0; o < k; o++)
        printf("%ld ", A[o]);

4 Востаннє редагувалося wander (07.11.2021 02:58:42)

Re: Два масиви цілих чисел.

litovskaolena написав:
*(A + q) = *(A + ++q)

1. UB till c++17, see: Order of evaluation
2. Навіть з с++17 краще так не писати.
3. Писати A[q] замість *(А + q) релігія не дозволяє?

Подякували: litovskaolena, mimik2

5

Re: Два масиви цілих чисел.

1. Це ви спеціально зсунули рядок, щоб "виділити" його? Не робіть так. Додавайте коментарі. Погано вирівняний код важко читати.
2. continue там не потрібен.
3. "*(А + q) не зчитується як A[q]"? А чому він має зчитуватися? Він записується, він у лівій же частині оператора =.
4. В умові нічого не сказано про "за допомогою вказівників", чому б вам і дійсно не писати A[q], якщо так плутаєтеся?
5. Ви значення q починаєте з 0 і двічі збільшуєте. Замініть ++q в тілі циклу на q+1.

wander, а до чого це тут? Тут же все на операторах і без постінкременту, преінкремент виконається до додавання, правий операнд присвоєння обчислиться до лівого.

Подякували: litovskaolena, leofun012

6

Re: Два масиви цілих чисел.

В умовах виконання лабки пише, що потрібно за допомогою вказівників робити(
Тут головне зрозуміти як перетворити

 A[i] = A[i+1] 

у вказівникову форму.

7

Re: Два масиви цілих чисел.

В умові нічого такого не сказано. Звісно, якщо ви надали нам всю умову, а не вирішили зекономити власний час на переписуванні умови.

8

Re: Два масиви цілих чисел.

І так, перетворюється це за стандартним принципом a[i] = *(a+i); але не треба так робити, програмування на вказівниках - це інший спосіб підходу до програмування, а не запису адресації масивів.

Подякували: litovskaolena1

9

Re: Два масиви цілих чисел.

я вже розв'язала і все працює, дякую за ваш час)

10

Re: Два масиви цілих чисел.

koala написав:

wander, а до чого це тут? Тут же все на операторах і без постінкременту, преінкремент виконається до додавання, правий операнд присвоєння обчислиться до лівого.

Для оператора присвоювання така гарантія є лише з С++17.

Подякували: litovskaolena, mimik2

11 Востаннє редагувалося lucas-kane (21.12.2021 23:06:28)

Re: Два масиви цілих чисел.

Щось мені здається, що на таке просте завдання і рішення має бути простим  :P
Зсунути і-й елемент вліво для того щоб "видалити" цей елемент, можна помінявши його місцями з початковим елементом масиву та змінити індекс початкового елементу на кількість "видалених" елементів масиву

Прихований текст
#include <stddef.h>
#include <stdio.h>

int main() {
  int a1[] = {-1, 2, 3, -4, 5, -4};
  int a2[] = {-1, -4};

  int t;

  size_t len1 = sizeof a1 / sizeof *a1;
  size_t len2 = sizeof a2 / sizeof *a2;

  size_t i, j, k = 0;
  for (i = 0; i < len2; i++) {
    j = k;
    while (j < len1) {
      if (a2[i] == a1[j]) {
        t = a1[k];
        a1[k] = a1[j];
        a1[j] = t;

        k++;
      }
      j++;
    }
  }

  printf("%zu\n", k);
  for (size_t i = k; i < len1; i++)
    printf("%d ", a1[i]);
  printf("\n");

  return 0;
}

Цей же алгоритм, тільки за допомогою вказівників...

Прихований текст
#include <stddef.h>
#include <stdio.h>

int main() {
  int a1[] = {-1, 2, 3, -4, 5, -4};
  int a2[] = {-1, -4};

  int *p1, *p2 = a2;
  int t;

  size_t len1 = sizeof a1 / sizeof *a1;
  size_t len2 = sizeof a2 / sizeof *a2;

  size_t k = 0;
  do {
    p1 = a1 + k;
    while (p1 != &a1[len1]) {
      if (*p2 == *p1) {
        t = *p1;
        *p1 = *(a1 + k);
        *(a1 + k) = t;

        k++;
      }
      p1++;
    }
    p2++;
  } while (p2 != &a2[len2]);

  printf("%zu\n", k);
  p1 = a1 + k;
  while (p1 != &a1[len1])
    printf("%d ", *p1++);
  printf("\n");

  return 0;
}

12

Re: Два масиви цілих чисел.

Якось елегантніше все ж по функціях розкидати.

#include <iostream>

/***
 * checks if value in array, returns true or false
 ***/
bool in_array(int value, int *array, std::size_t size)
{
    for(int *end=array+size; array<end; array++)
        if(*array==value)
            return true;
    return false;
}

/***
 *  Accepts arrays a and b; removes from a all values not present in b
 *  preserving order
 *  Returns new size of a
 ***/
int array_and(int *a, size_t size_a, int *b, size_t size_b)
{
    int *to = a;
    for(int *p=a, *end=a+size_a; p<end; p++)
        if(in_array(*p, b, size_b))
            *to++ = *p;
    return to-a;
}

int main() {
    int a1[] = {1, 2, 3, 4, 5, 4};
    std::size_t size_a1 = sizeof(a1)/sizeof(a1[0]);
    int a2[] = {4, 4, 1};
    std::size_t size_a2 = sizeof(a2)/sizeof(a2[0]);
    int new_size = array_and(a1, size_a1, a2, size_a2);
    for(int *p=a1, *end=a1+new_size;p<end;++p)
        std::cout<<*p<<" ";
    return 0;
}

13

Re: Два масиви цілих чисел.

wander написав:
koala написав:

wander, а до чого це тут? Тут же все на операторах і без постінкременту, преінкремент виконається до додавання, правий операнд присвоєння обчислиться до лівого.

Для оператора присвоювання така гарантія є лише з С++17.

Прихований текст

Перепрошую за підняття теми, але хіба ще не з С++11

і = ++і; // OK ?

wander, хіба тут не те саме?

14

Re: Два масиви цілих чисел.

mimik написав:
wander написав:
koala написав:

wander, а до чого це тут? Тут же все на операторах і без постінкременту, преінкремент виконається до додавання, правий операнд присвоєння обчислиться до лівого.

Для оператора присвоювання така гарантія є лише з С++17.

Прихований текст

Перепрошую за підняття теми, але хіба ще не з С++11

і = ++і; // OK ?

wander, хіба тут не те саме?

Ні, не те саме.
Для порівняння (я розкрив оператор ++):

i = ++i;      -> i = i = i + 1;
a[i] = a[++i] -> a[i] = a[i = i + 1];
Подякували: mimik1