Tablica dynamiczna usuwanie elementu

0

Cześć.
Natrafiłem na taki problem, potrzebuje usunąć tylko pierwszy wskazany element np. jeśli mam kilka trojek chce żeby zniknęła tylko pierwsza napotkana.
Bardzo będę wdzięczny za wskazówki bądź gotowe rozwiązanie.

int main()
{
    int* wskaznik = NULL;
    int ile;
    int cyfry;

    cout << "podaj dlugosc listy\n";
    cin >> ile;

    wskaznik = new int[ile];
    cout << "podaj cyfry do listy\n";

    for (int i = 0; i < ile; i++) {
        cin >> cyfry;
        wskaznik[i] = cyfry;
    }

    for (int i = 0; i < ile; i++)
        cout << wskaznik[i] << ",";

    int* n_wskaznik = new int[ile - 1];

    int usun;
    / int j = 0;
    cin >> usun;

    int znajdz = 0; // potrzebny mechanizm wybierający tylko pierwszy element

    for (int i = 0; i < ile; i++) {
        if (usun != wskaznik[i]) // '==' pokarze wybrane,  '!+' usunie wybrane
        {

            n_wskaznik[j] = wskaznik[i];
            j++;
            cout << wskaznik[i] << ",";
        }
    }
    return 0;
}
0

Mozesz użyć jakis kontenerów? Jak forward_list, czy vector?

0

Mógłbym, ale wróciłem do tego zagadnienia z ciekawości i dalej nie mogę wykombinować jak, a pewnie jednym bool'em można ta sprawę załatwić :)

0

Po co się męczyć, jak masz gotowe rozwiązanie praktycznie? std::multiset + erase + multisetowe equal_range.first

0

Możesz iterować po strukturze, i jak Napotkasz element, równy, np., 3, to go usunąć i wywołac break. Problemy są inne, co jak go nie napotkasz, czy funkcja ma coś zwracać?, NULLA? Czy może ma być void? jedno i drugie zuo. Gdy Usuniesz element, to co z resztą Przesuwasz je w prawo [edit: w lewo]? Zmniejszasz tablicę? Ma być w pełni dynamiczna?

0

Myślałem o czymś takim. Leci wskaźnik po intach, jak nie napotka zadanej wartości przepisuje tablice, a jak wyhaczy to pierwszy który się zgadza to kończy porównanie przepisuje resztę , przesuwa wartości, zmiesza tablice,koniec.

0

To Pisz i Wrzucaj, to nie jest rocket science.

0

Problemy, które ja zauważam:
-Nie zwalniasz pamięci.
-int* n_wskaznik = new int[ile - 1]; prowadzi do UB jeżeli nie znajdziesz elementu do usunięcia.

Reszta wygląda w miarę spoko.
To, co ja bym zrobił, to zrezygnował z gołych pętli i zaprzęgł do tego std::find():

auto end = std::next(wskaznik, ile);
auto found_at = std::find(wskaznik, end, usun);
std::copy(wskaznik, found_at, n_wskaznik);
if(found_at == end || std::next(found_at) == end)
    return; // robota zrobiona

const auto already_copied_count = std::distance(wskaznik, found_at);
std::copy(std::next(found_at), end, std::next(n_wskaznik, already_copied_count));

EDIT
Co ciekawe, można to rozpykać takim brzydkim jednolinijkowcem:

auto copied_end = std::copy_if(wskaznik, std::next(wskaznik, ile),
							   n_wskaznik,
							   [usun, found = false](const auto element) mutable
							   {
							 	  return found || !(found = usun == element);
							   });
std::copy(n_wskaznik, copied_end, std::ostream_iterator<int>(std::cout, ", "));
0

Tak, mniej wiecej, to Musisz napisać klasę. Najprostszy z najprostszych poczatków:

#include <iostream>

class Vector {
	
	public:
	int * a;
	Vector (int len) {
		a = new int[len];
		size = 0;
	}
	int length() {
		return size;
	}
	void pop(int elem) {
		for (int i = 0; i < size; i++) {
				if (a[i] == elem) 
					_remove(i);
		}
	}
	void push(int elem) {
		a[size] = elem;
		size++;
	}
	private:
	int size;
	void _remove(int i) {
		for (int k = i; k < size - 1; k++)
			a[k] = a[k+1];
		size--;
	}

 };

int main() {
	Vector v1(4);
	v1.push(1);
	v1.push(2);
	v1.push(3);
	for (int i = 0; i < v1.length(); i++) 
		std::cout << v1.a[i] << " ";  // -> 1 2 3
	std::cout << "\n";
	v1.pop(1);
	for (int i = 0; i < v1.length(); i++) 
		std::cout << v1.a[i] << " "; // -> 2 3
	std::cout << "\n";
	return 0;
}

Sorry za to tępe 1 2 3 :-D. Nie ma tam, kontroli pamięci, kontroli dodawania elementów, ale zaczynając od tego Dodajesz kolejne rzeczy. Może Napiszesz coś lepszego niż std::vector? Taki żart, rozumiem, że Eksperymentujesz w C++, żeby napisać taki container w jakiś języku, który go nie ma.

0

A jednak urodziłem to jednym bool'em ;)

int main()
{
    int* wskaznik = NULL;
    int ile;
    int cyfry;

    cout << "podaj dlugosc listy\n";
    cin >> ile;

    wskaznik = new int[ile];
    cout << "podaj cyfry do listy\n";

    for (int i = 0; i < ile; i++) {
        cin >> cyfry;
        wskaznik[i] = cyfry;
    }

    for (int i = 0; i < ile; i++)
        cout << wskaznik[i] << ",";

    int* n_wskaznik = new int[ile - 1];

    int usun;
    int j = 0;
    cin >> usun;

    bool znajdz = false;

    

    for (int i = 0; i < ile; i++) {
        if (usun != wskaznik[i]) // '==' pokarze wybrane,  '!+' usunie wybrane
        {

            n_wskaznik[j] = wskaznik[i];
            j++;

        }
else if (usun==wskaznik[i] && znajdz==false) {
                znajdz=true;
            }

             else if (usun==wskaznik[i] && znajdz==true) {
                n_wskaznik[j]=wskaznik[i];
                j++;
          }
    }
for (int i=0;i<ile-1;i++)
             cout<< n_wskaznik[i];

    return 0;

}

1 użytkowników online, w tym zalogowanych: 0, gości: 1