C++ vector is declared 1D but accessed in a 2D way - c++

I found some C++ code on the internet and I had a problem trying to understand it. So I have an array of Strings called vetor with 105 positions. After the declaration there's an if statement that tries to access the array like a matrix. How is that possible?
string vetor[105];
for(int k = 0; k < n; ++k) {
bool ok = true;
for(int i = 0, i < (int((text).size()))-(int((vetor[k]).size()))+1; ++i) {
ok = true;
for(int j = 0, j < (int((vetor[k]).size())); ++j) {
if(text[i+j] != vetor[k][j]) {
ok = false;
break;
}
}
if(ok) {
res.push_back(ii(i, i-1+(int((vetor[k]).size()))));
}
}
}

Related

error request for member .. in .. which is of non-class type - C++

I have got this error: "error: request for member 'nume' in 'tablou[j]', which is of non-class type ' [100]'", and I don't really know how to solve it.I tried searching on youtube and google but I found nothing .Does anyone have any ideas for how to solve this?
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
struct{
int counter;
char nume[20] = " ";
}tablou[10][100];
int main()
{
int n, counter = 0;
char second[10][100];
bool verify = true;
cout<<"Cate nume?";
cin>>n;
for(int i = 0; i <= n; i++)
{
cin.getline(second[i],20);
}
for(int i = 0; i <= n; i++)
{
verify = true;
for(int j = 0; j < i; j++)
{
if(strcmp(second[i], tablou[j].nume) == 0)
{
verify = false;
}
}
if(verify == true)
{
strcpy(tablou[i].nume, second[i]);
for(int k = 0; k < n; k++)
{
if(strcmp(tablou[i].nume, second[k]))
{
tablou[i].counter++;
}
}
}
}
for(int i = 0; i <= n; i++)
{
cout<<tablou[i].nume<<" "<<tablou[i].counter<<endl;
}
return 0;
}
tablou is a 2d array
struct{
int counter;
char nume[20] = " ";
}tablou[10][100];
its elements are tablou[x][y]
you try to access an element with only one index
if(strcmp(second[i], tablou[j].nume) == 0)
----------------------------^
I do not know what your code is trying to do , but thats why you get the error
The array tablou is a two-dimensopnal array
struct{
int counter;
char nume[20] = " ";
}tablou[10][100];
So for example the expression tablou[j] has the array type the_unnamed_structure[100].
So such an expression like this
tablou[j].nume
is incorrect and the compiler issues an error.
Maybe actually you mean the following declaration of the array
struct{
int counter;
char nume[20] = " ";
}tablou[10];
Also in these loops
for(int i = 0; i <= n; i++)
{
verify = true;
for(int j = 0; j < i; j++)
{
if(strcmp(second[i], tablou[j].nume) == 0)
{
verify = false;
}
}
if(verify == true)
{
strcpy(tablou[i].nume, second[i]);
for(int k = 0; k < n; k++)
{
if(strcmp(tablou[i].nume, second[k]))
{
tablou[i].counter++;
}
}
}
}
some elements of the array tablou can be skipped if verify is set to false because you are using the index i to assign elements of the array tablou. That is the number of actual elements of the array tablou can be less than n. In this case this for loop
for(int i = 0; i <= n; i++)
{
cout<<tablou[i].nume<<" "<<tablou[i].counter<<endl;
}
will invoke undefined behavior because the data member counter will be uninitialized for some outputted elements of the array.
You need to support a separate variable as an index in the array tablou.

C++: How to make break/continue in nested loops

How to beautifully implement the following code?
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < l; k++) {
if (condition1) {
// continue at for k ...
}
if (condition2) {
// continue at for j ...
}
if (condition3) {
// continue at for i ...
}
}
}
}
Usually I'll go with three boolean flag, and after each iteration will check it whether I should break/continue. Is there better way to do that? I was taught never to use goto/labels but looks like it might be useful here?

How can I not allow an element in an array to not increment if it was already incremented on that run in the loop?

I am trying to get the summary of CFG with given input. I have to list the terminals with the count of how many times it appears in the rule. However, I'm having trouble with it counting multiple terminals on the same rule.
for (int i = 0; i < cfg.size(); i++)
{
for (int j = 0; j < cfg[i].size(); j++)
{
for (int k = 0; k < terminal.size(); k++)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
//TO-DO if counter[k] already incremented do not increment counter[k] again
counter[k]++;
break;
}
}
}
}
For example if the rule is
Z -> a b b b
It will return 3 for b when the correct answer would be 1.
Any help on how I can how I can leave that rule after it has already been counted would be great. Thank you
I'm not sure if I understand what you mean, but maybe changing the loops order would help?
for (int i = 0; i < cfg.size(); ++i)
{
for (int k = 0; k < terminal.size(); ++k)
{
for (int j = 0; j < cfg[i].size(); ++j)
{
if (strcmp(cfg[i][j].c_str(), terminal[k].c_str()) == 0)
{
++counter[k];
break;
}
}
}
}

Unique set of words from string C++

I am trying to write a function that inputs an array_string and finds unique words, then copies them over to unique_array. This is a bit over my head I feel like and need some advice on where to go from here..
void unique140(string str_array[], int array_size, string unique_array[], int&unique_size)
{
int i = 0;
int j = 0;
for(i = 0; i < array_size; i++)
{
for(j = 0; j < unique_size; j++)
if (str_array[i] != unique_array[j])
{unique_array[i];}
if(str_array[i] == unique_array[j]
break;
}
Try something like:
void unique140(string str_array[], int array_size,
string unique_array[], int&unique_size)
{
unordered_map<string,int> count;
for(int i=0; i<array_size; i++) {
count[str_array[i]]++;
}
unique_size = 0;
for(auto it=count.begin(); it!=count.end(); ++it) {
if(it->second==1) {
unique_array[unique_size++] = it->first;
}
}
}
use a std::map if you dont have a std::unordered_map.
You're not a million miles away, the loops look good. Now you have to use those loops to make a decision, is the word str_array[i] present in the unique_array or not? Now just a minutes thought will tell you that str_array[i] is present if any one of the equality tests str_array[i] == unique_array[j] is true. Here's how to code that
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
...
}
Next we have to add str_array[i] to unique_array if it's not already there. So that's
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
if (!in_unique_array)
{
...
}
}
Finally having decided to add the string to unique_array we have to do that
for(i = 0; i < array_size; i++)
{
bool in_unique_array = false;
for(j = 0; j < unique_size; j++)
if (str_array[i] == unique_array[j])
in_unique_array = true;
if (!in_unique_array)
{
unique_array[unique_size] = str_array[i];
unique_size++;
}
}

Memory issues with two dimensional array

Following this nice example I found, I was trying to create a function that dynamically generates a 2D grid (two dimensional array) of int values.
It works fairly well the first couple of times you change the values but if crashes after that. I guess the part where memory is freed doesn't work as it should.
void testApp::generate2DGrid() {
int i, j = 0;
// Delete previous 2D array
// (happens when previous value for cols and rows is 0)
if((numRowsPrev != 0) && (numColumnsPrev != 0)) {
for (i = 0; i < numRowsPrev; i++) {
delete [ ] Arr2D[i];
}
}
// Create a 2D array
Arr2D = new int * [numColumns];
for (i = 0; i < numColumns; i++) {
Arr2D[i] = new int[numRows];
}
// Assign a random values
for (i=0; i<numRows; i++) {
for (j = 0; j < numColumns; j++) {
Arr2D[i][j] = ofRandom(0, 10);
}
}
// Update previous value with new one
numRowsPrev = numRows;
numColumnsPrev = numColumns;
}
I see 1 major bug:
// Assign a random values
for (i=0; i<numRows; i++){
for (j=0; j<numColumns; j++){
Arr2D[i][j] = ofRandom(0, 10);
}
}
Here the variable 'i' is used as the first index into 'Arr2D' and goes to a max of (numRows -1)
While in this code:
for (i=0; i<numColumns; i++)
{
Arr2D[i] = new int[numRows];
}
The variable 'i' is used as the first index but goes to a max of (numColumns-1). If numRows is much larger than numColumns then we are going to have a problem.
As a side note. When you try and clean up you are leaking the columns:
if((numRowsPrev != 0) && (numColumnsPrev != 0))
{
for (i=0; i<numRowsPrev; i++){
delete [ ] Arr2D[i];
}
// Need to add this line:
delete [] Arr2D;
}
Next thing to note.
This is truly not a good idea. Use some of the provided STL classes (or potentially boost Matrix). This looks like you are binding global variables and all sorts of other nasty stuff.
2-dim array in C++ with no memory issues:
#include <vector>
typedef std::vector<int> Array;
typedef std::vector<Array> TwoDArray;
Usage:
TwoDArray Arr2D;
// Add rows
for (int i = 0; i < numRows; ++i) {
Arr2D.push_back(Array());
}
// Fill in test data
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
Arr2D[i].push_back(ofRandom(0, 10));
}
}
// Make sure the data is there
for (int i = 0; i < numRows; i++) {
for (int j = 0; j < numCols; j++) {
std::cout << Arr2D[i][j] << ' ';
}
std::cout << '\n';
}