C++ check if element exists in array - c++

I've found a lot of topics like this, but it was kinda too complicated for me.
How to check if element exists in an array?
first I declare an array and put values in it
for(int l=0;l<=21;l++){
skirt[l]=l;
}
and then with another for I'd like to check if any element which exist in other array is in array skirt[];
Is there a way to write it something like this?
for(int k=0;k<=n;k++){
if(skaiciai[k]!=skirt[k]){
counter++;
}
}

The best way to do this would be to use standard algorithm, rather than a handwritten loop:
if (std::find_first_of(
skirt, skirt + skirt_size,
skaiciai, skaiciai + skaiciai_size)
!= skirt + skirt_size)
{
//skirt contained an element from skaiciai
}

The loop:
for(int k=0;k<=n;k++){
if(skaiciai[k]!=skirt[k]){
counter++;
}
}
would only compare elements at the same index in the arrays. Nested for loops are required with the outer for loop iterating over the elements in one array and the inner for loop iterating over elements in the other array:
for (int k_skirt = 0; k_skirt <= n; k_skirt++)
{
for (int k_skaiciai = 0; k_skaiciai <= n; k_skaiciai++)
{
if(skaiciai[k_skaicia] == skirt[k_skirt]){
counter++;
}
}
}

You could simply use the std::count algorithm.
auto counter = std::count( skirt, skirt+skirt_size );

Related

How can I find repeated words in a vector of strings in C++?

I have a std::vector<string> where each element is a word. I want to print the vector without repeated words!
I searched a lot on the web and I found lots of material, but I can't and I don't want to use hash maps, iterators and "advanced" (to me) stuff. I can only use plain string comparison == as I am still a beginner.
So, let my_vec a std::vector<std::string> initialized from std input. My idea was to read all the vector and erase any repeated word once I found it:
for(int i=0;i<my_vec.size();++i){
for (int j=i+1;j<my_vec.size();++j){
if(my_vec[i]==my_vec[j]){
my_vec.erase(my_vec.begin()+j); //remove the component from the vector
}
}
}
I tried to test for std::vector<std::string> my_vec{"hey","how","are","you","fine","and","you","fine"}
and indeed I found
hey how are you fine and
so it seems to be right, but for instance if I write the simple vector std::vector<std::string> my_vec{"hello","hello","hello","hello","hello"}
I obtain
hello hello
The problem is that at every call to erase the dimension gets smaller and so I lose information. How can I do that?
Minimalist approach to your existing code. The auto-increment of j is what is ultimately breaking your algorithm. Don't do that. Instead, only increment it when you do NOT remove an element.
I.e.
for (int i = 0; i < my_vec.size(); ++i) {
for (int j = i + 1; j < my_vec.size(); ) { // NOTE: no ++j
if (my_vec[i] == my_vec[j]) {
my_vec.erase(my_vec.begin() + j);
}
else ++j; // NOTE: moved to else-clause
}
}
That is literally it.
You can store the element element index to erase and then eliminate it at the end.
Or repeat the cycle until no erase are performed.
First code Example:
std::vector<int> index_to_erase();
for(int i=0;i<my_vec.size();++i){
for (int j=i+1;j<my_vec.size();++j){
if(my_vec[i]==my_vec[j]){
index_to_erase.push_back(j);
}
}
}
//starting the cycle from the last element to the vector of index, in this
//way the vector of element remains equal for the first n elements
for (int i = index_to_erase.size()-1; i >= 0; i--){
my_vec.erase(my_vec.begin()+index_to_erase[i]); //remove the component from the vector
}
Second code Example:
bool Erase = true;
while(Erase){
Erase = false;
for(int i=0;i<my_vec.size();++i){
for (int j=i+1;j<my_vec.size();++j){
if(my_vec[i]==my_vec[j]){
my_vec.erase(my_vec.begin()+j); //remove the component from the vector
Erase = true;
}
}
}
}
Why don't you use std::unique?
You can use it as easy as:
std::vector<std::string> v{ "hello", "hello", "hello", "hello", "hello" };
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());
N.B. Elements need to be sorted because std::unique works only for consecutive duplicates.
In case you don't want to change the content of the std::vector, but only have stable output, I recommend other answers.
Erasing elements from a container inside a loop is a little tricky, because after erasing element at index i the next element (in the next iteration) is not at index i+1 but at index i.
Read about the erase-remove-idiom for the idomatic way to erase elements. However, if you just want to print on the screen there is a much simpler way to fix your code:
for(int i=0; i<my_vec.size(); ++i){
bool unique = true;
for (int j=0; j<i; ++j){
if(my_vec[i]==my_vec[j]) {
unique = false;
break;
}
if (unique) std::cout << my_vec[i];
}
}
Instead of checking for elements after the current one you should compare to elements before. Otherwise "bar x bar y bar" will result in "x x bar" when I suppose it should be "bar x y".
Last but not least, consider that using the traditional loops with indices is the complicated way, while using iterators or a range-based loop is much simpler. Don't be afraid of new stuff, on the long run it will be easier to use.
You can simply use the combination of sort and unique as follows.
#include <iostream>
#include <algorithm>
#include <vector>
int main() {
std::vector<std::string> vec{"hey","how","are","you","fine","and","you","fine"};
sort(vec.begin(), vec.end());
vec.erase(unique(vec.begin(), vec.end() ), vec.end());
for (int i = 0; i < vec.size(); i ++) {
std::cout << vec[i] << " ";
}
std::cout << "\n";
return 0;
}

Can you change a pointer in loop?

Let's say I have a vector of integers:
vector<int> v(n);
Which I fill up in a for loop with valid values. What I want to do is to find a index of a given value in this vector. For example if I have a vector of 1, 2, 3, 4 and a value of 2, i'd get a index = 1. The algorithm would assume that the vector is sorted in ascending order, it would check a middle number and then depending of it's value (if its bigger or smaller than the one we're asking for) it would check one of halves of the vector. I was asked to do this recursive and using pointer. So I wrote a void function like:
void findGiven(vector<int> &v){
int i = 0;
int *wsk = &v[i];
}
and I can easily access 0th element of the vector. However I seem to have some basic knowledge lacks, because I can't really put this in a for loop to print all the values. I wanted to do something like this:
for (int j = 0; j<v.size(); j++){
cout << *wsk[j];
}
Is there a way of doing such a thing? Also I know it's recurisve, I'm just trying to figure out how to use pointers properly and how to prepare the algorithm so that later I can build it recursively. Thanks in advance!
The correct way is:
for (int wsk : v) {
cout << wsk;
}
If you insist on pointers:
int* first = v.data();
for (size_t j = 0; j < v.size(); ++j) {
cout << first[j];
}

deleting multiple elements in an array

i am trying to write a code that will delete all the elements if an array has same element at different index . it works fine for one element deletion or elements at odd index i.e 1,3,5 etc but it neglects one element if the consecutive index have same element.
i have just tried this to get my hands on arrays
for(int i=0;i<n;i++) //for deletion
{
if(arr[i]==_delete)
{
arr[i]=arr[i+1];
--n;
}
}
I suggest you use std::vector as a container for your objects.
std::vector<TYPE> vec ;
// initialise vector
You can use
vec.erase(std::remove_if(vec.begin(), vec.end(),
[](const auto & item){return item == _delete;}), vec.end());
Alternatively, you can use std::list. Its list::erase has linear time complexity.
As an additional solution, if you want to deal with built-in C++ arrays, the standard std::remove algorithm can be rewritten like this:
void remove(int _delete) {
int j = 0;
for (int i = 0; i < n; ++i) {
if (arr[i] != _delete) {
arr[j++] = arr[i];
}
}
// update the size!
n = j;
}
It's quite pretty:
We keep in the array the elements we only need, and override the ones in which we are not interested (they can be either equal or not to _delete and start at position j till the end)

How to assign values to struct?

I have a struct to assign values to it. But my programm crashs it. Hopefully you can help me.
struct HashEntry{
std::string key; //the key of the entry
bool used; //the value of the entry
int value; //marks if the entry was used before
};
HashEntry *initHashList(int N){
HashEntry* hashList = new HashEntry[N];
for (int i = 0; i <= N; i++){
hashList[i].key = " ";
hashList[i].value = -1;
hashList[i].used = false;
}
for(int i = 0; i <N; i++){
cout<<hashList[i].value<<endl;
}
return hashList;
}
You iterate through one element too many on creation:
for (int i = 0; i <= N; i++){
Shoule be
for (int i = 0; i < N; i++){
It's because with arrays being 0-based, you can't access the element N of an array of the size N, only N-1, but in return also element 0.
Also, to make the code clearer and less error prone, you could use std::array instead of a pure C style array, or even an std::vector to be able to loop through them range based. You might also rething your use of new which should be avoided in most cases. If you don't really need that, I'd change the function to
std::vector<HashEntry> initHashList(int N) {
std::vector<HashEntry> hashList(N, { "", false, -1, }); //Creating vector of N elements
for (const HashEntry& entry : hashList) { //Iterating through the elements
std::cout << entry.value << std::endl;
}
return hashList;
}
I hope this makes it clearer how you can approach such a problem.
This way of creating the vector and looping through it avoids the potential access errors and is easier to read, imo. For more information, search for std::vector, its constructors, and range-based loops.

loop through an array in c++

I want to loop through an array that I have that has a max value of 1000. I am filling the array with values from a text file. I am trying to loop through that array but in my for loop, I do not know the length of the array, so I do not know what to put in the second part of the for loop statement. For example: I have an array called: int scores[1000]; and I am trying to iterate through this array and putting scores in a grade category. So A = 90-100, B = 80-89, C = 70-79, D = 60-69, F = 0-59.
So I dont know what my for loop would look like:
for(int i = 0; i < ...; i++){
if(scores[i] > = 90 || scores[i] <= 100){
//Do stuff...
}
I guess I am also confused as to how to get the total counts of each category at the end too. But for the most part its how to iterate through this array. I know sizeof(scores[]) wont work because that will give me the int size and not the length of the array itself. Thanks though in advance!
Actually the sizeof() should be done like this:
sizeof(scores) / sizeof(scores[0])
And this will give you the total element numbers of the array.
If you use an std::vector (link) instead, you can add elements and have the vector dynamically change size. That size can be queried easily using the size() method. If you use arrays like this, you have to keep track of the number of elements in it yourself.
If you have a vector filles with elements your loop could look like this:
std::vector<int> scores;
// fill vector
for (unsigned int i=0; i<scores.size(); i++) {
// use value
}
If you have to use arrays and actually have a scoreCount variable with the number of real values put in there, simply use that in your loop:
for (int i=0; i<scoreCount; i++) {
// use value
}
A third option, as I mentioned in the comments, would be initializing the whole array with a value that you're never using (typically -1) and then use that as a marker for filled vs empty array positions like so:
for (int i=0; i<1000; i++) {
scores[i] = -1;
}
// add real values to scores
int i=0;
while (scores[i] != -1 && i < 1000) {
// use value
i++;
}
When you populate the scores array, you need to actually count how many items you put in it. Then you remember that number and use it for iteration later. For example, you may have read your scores like this:
// Read some scores: Stop when -1 is entered, an error occurs, or 1000 values are read.
int num_scores = 0;
for( ; num_scores < 1000; num_scores++ )
{
if( !(cin >> scores[num_scores]) || scores[num_scores] == -1 ) break;
}
// Do stuff with scores...
for(int i = 0; i < num_scores; i++) {
...
}
There are some other options to consider:
use a sentinel value to represent the end of data, such as a score of -1.
use a std::vector instead.
By the way, the logical statement inside your loop will always be true. Are you sure you didn't mean to use && instead of ||?
If you really want to use a container with a fixed size, use std::array for modern C++ instead of a C-array:
#include <array>
std::array<std::int32_t, 1000> scores;
for (std::size_t i{0}; i < scores.size(); ++i) {
// Do stuff...
}
Otherwise use a std::vector:
#include <vector>
std::vector<std::int32_t> scores;
for (std::size_t i{0}; i < scores.size(); ++i) {
// Do stuff...
}
If you are able to use C++11 I also recommend to use the fixed width integer types.