How did a vector become a matrix? - c++

So I found this code on the internet, but as I'm not that familiar with C++. I found difficult to understand this: how does a vector suddenly becomes a matrix?
int main(){
int n;
string v[MAX];
cin >> n;
for(int i=0;i<n;i++)
cin >> v[i];
for(int i=0;i<n-1;i++){
int y1,y2;
y1=v[i].size();
y2=v[i+1].size();
for(int j=0; j<y1 && j<y2 ;j++)
if(v[i][j]!=v[i+1][j]){ // here <-
int x1,x2;
x1=(int) v[i][j]-'A';
x2=(int) v[i+1][j] - 'A';
m[x1][0]=true;
m[x2][0]=true;
m[x1][x2+1]=true;
break;
}
}

string v[MAX];
is an array of std::string (presumably - this is one reason to avoid using namespace std;. How do I know what type of string it is?).
You can access elements of an array with []:
int someInts[5];
someInts[3]=1000; // sets the 4th int (counting starts from 0)
You can also access characters in a std::string with []:
std::string name("chris");
std::cout << name[3]; // prints 'i'
So you can access the letters in an array of std::strings with two sets of []:
std::string names[10]; // 10 names
names[3] = "chris"; // set the 4th name
std::cout << names[3][1]; // prints 'h'
// ^ access letter in string
// ^ access string in array

Here is a self-explanatory example
int main()
{
std::string name;
name = "test";
for(int i = 0; i<4; i++)
std::cout<<name[i]<<std::endl;
std::cout << "Hello, " << name << "!\n";
}
It will print
t
e
s
t
Hello, test!
So, an array of strings is actually a 2D array of characters, that you called a matrix.

string v[N] is an array of string, string itself is an array of chars.

Since, as the commentor pointed out, there are neither vectors or matrices in the code you gave, I'll make a couple assumptions:
By "vector", you mean "array"
You think that double square brace operators ([][]) indicate a matrix.
If those are both true, I can explain what you're seeing:
string[5] strings = { Some Strings... }
//The first string in the array
string string1 = strings[0];
//The first letter of the first string
char char1 = string1[0];
//The above is the same as:
char char1Again = strings[0][0];
In the line above, the first square bracket operator returns the first string in the array. The second square bracket operator is then applied to that string, which returns the first character of that string.
This works because both arrays and Strings (which are really arrays themselves deep down) implement the square bracket operator to access their internal elements by index.
Technically, in a convoluted way, you could call this a matrix, but "2D array of characters" would be more appropriate.

Related

Reversing string C++

I tried to create a code that reverse a string, I think my loops logic is correct. But I don't know what is wrong.
#include <iostream>
int main(){
std::cout<<"How many letters does your string have >> ";
int nbre;
std::cin>> nbre;
int a;
a=nbre-1;
char normal[a]={};
char reverse[a]={};
std::cout<<"Enter your string >> ";
std::cin >> normal;
for (int i=0;i<=a;i++){
normal[i]=reverse[a-i];
}
std::cout << "The reversed string is >> " << std::endl;
for (int u=0; u<=a; u++){
std::cout<<reverse[u];
}
return 0;
}
enter image description here
You have to use constant to declare an array this way:
char normal[a]={};
char reverse[a]={};
You can allocate memory like this instead:
char* normal = (char*)calloc(a+1, sizeof(char));
char* reverse = (char*)calloc(a+1, sizeof(char));
and free it once done using it.
The +1 is because you have to account for the ending null char.
I don't think letting the user account for it is a good idea unless your users will only be C-programmers... Better change a = nbre-1; to a=nbre;.
Finally, you should have meant to write your for-loop as:
for (int i = 1; i <= a; i++) {
reverse[i-1] = normal[a - i];
}
I made many changes to your for loop. I will let you do the Homework to understand why.
Personally, I would load the input string into a char array and iterate backwards, starting at the end of the input array and just doing some index math.
Let n = input string length
Iterate from i = n-1 to 0, and load input[i] into reversed[n-i]. Luceion is correct; you're not doing the correct method of actually reversing input string in the first for loop.

Trouble converting vector to string

Basically I just need to fill the string with all the letters from the vector. The vector is of type char, but it shouldn't matter right? When I debugged it, it said the size of string was still 0? Here's a snippet of code.
NOTE: Vector size is 7 (tested in output) so the problem doesn't seem to lie in the vector.
vector<char> final; //note this gets filled before reaching the loop
// fills vector in here, size is now 7
string* complete;
complete = new string[final.size()]; //set size of string to vector size
//debugger says size of complete is 0????
for (int i = 0; i < final.size(); i++) {
complete[i] = final[i]; //should fill string
}
cout << "COMPLETE:" << *complete << endl; //one letter output
Here's a one-liner to do it:
string complete(final.begin(), final.end());
or:
string complete(final.data(), final.size());

C++ Copying an array of chars using char* (no string libraries)

I am writing a C++ function that is supposed to duplicate an array of chars by copying each element character-by-character into a new array. Ideally, if I make the statements
char* a = "test";
char* b = copyString(a);
then both a and b should contain the string "test." However, when I print the copied array b, I get "test" plus a series of nonsense characters that seem to be the pointer. I don't want those, but I can't figure out where I'm going wrong.
My current function is as follows:
char* copyString(char* s)
{
//Find the length of the array.
int n = stringLength(s);
//The stringLength function simply calculates the length of
//the char* array parameter.
//For each character that is not '\0', copy it into a new array.
char* duplicate = new char[n];
for (int j = 0; j < n; j++)
{
duplicate[j] = s[j];
//Optional print statement for debugging.
cout << duplicate[j] << endl;
}
//Return the new array.
return duplicate;
}
For the purposes of understanding certain aspects of C++, I cannot use string libraries, which is where other answers I have found have fallen short in this case. Any help with this problem is greatly appreciated.
EDIT: I though my stringLength function was fine - perhaps I was wrong.
int stringLength(char* s)
{
int n;
//Loop through each character in the array until the '\0' symbol is found. Calculate the length of the array.
for (int i = 0; s[i] != '\0'; i++)
{
n = i + 1;
}
//Optional print statement for debugging.
// cout << "The length of string " << s << " is " << n << " characters." << endl;
return n;
}
You need to copy the 0 too. That's what a C-style string is, a null-terminated character array.
Really, all you need to do is add one to the length:
int n = stringLength(s) + 1; // include the '\0'
And then everything else will account for itself - you'll allocate an array of sufficient size, and copy the '\0' in your loop too.

Is the initialization of the empty char array valid?

int main()
{
cout<<"Enter a word"<<endl;
char word1[]={0}; //first char array initialization
cin>>word1;
cout<<"Enter another word"<<endl;
char word2[]={0}; //second char array initialization
cin>>word2;
char word3[]={0};
char word4[]={0};
int i=0;
while (word1[i]!='\0') //this converts both words to lower case by usinction tolower
{
word3[i]=char(tolower(word1[i])); //word3 and word4 stores the new arrays
word4[i]=char(tolower(word2[i]));
i++;
}
int output; //output stores the value of 0,1 or -1
output=compareString(word3,word4);
if (output==0)
{
cout<<"The two words are the same."<<endl; //if arrays are same
}
if (output==1)
{
cout<<"the 1st character of 1st word has a larger value than of 2nd word."<<endl;
}
if (output==-1)
{
cout<<"the 1st character of 2nd word has a larger value than of 1st word."<<endl;
}
return 0;
}
int compareString(char string1,char string2)
{
int size1=0; //initialize size of string1
int j=0; //string1 position initialize
while (string1[j]!='\0') //loop to determine size of string1
{
size1+=1;
j+=1;
}
int a=0; //initialize size of string2
int size2=0; //string2 position
while (string2[a]!='\0') //loop determines size of string2
{
size2+=1;
a+=1;
}
int i=0;
int k=0;
for (i=0;i<size1;i++) //loop to compare the two strings
{
if (string1[i]!=string2[i])
{
if (string1[i]>string2[i]) //comparing 1st character of string1 & string2
{
return 1;
}
else //if string2's first character is greater in value
{
return -1;
}
}
else
{
k++; //incrementing k when character of string1 matches string2 character
}
}
if (k==size1) //to cjheck if all characters of both strings are same
{
if (k==size2)
{
return 0;
}
}
}
This is a function which compares two char arrays and returns 0 if characters correspond to each other,returns 1 if first character of string1 is greater than first character of string2 in value and returns -1 if first character of string1 is less than first character of string2.The problem is that when i run it,even when the two words are different,the output is always 0 and the text "The words are the same" appears.
Am i initializing the two arrays correctly in my main program?or is there some other problem?
This declaration
char word1[]={0};
declares an array of size 1, meaning when you do your input it will overwrite the stack. The same for all other arrays.
When dealing with string in C++ it is highly recommended to use std::string!
char word1[]={0};
This line creates an array word1 that has exactly one element, set to 0. When using this array to hold a string, you cannot hold anything in this except the empty string. You are causing a buffer overflow here, because you read a non-empty string into this array, which will then write into other parts of memory not allocated to this array. This is very bad.
Consider using std::string to hold strings instead. It will automatically resize its allocation as necessary.

How do effectively use the string data_type in C++?

I tried making this small program that takes input and checks for vowels. If there are vowels then it appends them to a string and returns the size of the string.
My only problem is I can't get it to work using strings. What is the major difference over using character arrays? I can get the program to work using something like:
char entered[128];
//and then
char exceptions[11] = "aeiouAEIOU";
**Quick question about the above array. When I assign the buffer to 'exceptions' it has to be 11 or the compiler will error. Must I manually account for the NULL termination portion?
If I do something like:
if(cPtrI[i] == 'a'){
I get an error stating unknown operator '==' ??
I thought '==' was a check operator, and '=' was an assignment operator?
no match for 'operator==' in '*((+(((unsigned int)i) * 4u)) + cPtrI) == 'a''|
AND, if I do something like: (which I thought was correct, at first)
if(*cPtrI[i] == *cPtrJ[j]){
I get the same error as above, but referencing unknown operator *:
no match for 'operator*' in '**((+(((unsigned int)i) * 4u)) + cPtrI)'|
no match for 'operator*' in '**((+(((unsigned int)j) * 4u)) + cPtrJ)'|
I thought the * operator said, in effect, 'what is at' the address of where the pointer is pointing.
So, something like the above would read:
If(What is at index I of string 'a' EQUALS What is at index J of string 'exceptions'){
then ..
Any help with this one? I learned C a bit before C++, so perhaps this is where my confusing is coming from. It was my understanding the the above code would compare addresses of characters/variables they are pointing to. * indicates 'what is at' while just placing the pointer name would indicate the value the pointer is holding(which is an address of the variable being pointed to). Using &ptrName would be the address of the pointer itself, correct? Where have I gone wrong here?
#include <iostream>
#include <string>
int vowelCheck(std::string a);
int main()
{using namespace std;
string eString;
cout << "Enter a string: ";
cin >> eString;
cout << "There were " << vowelCheck(eString) << " vowels in that string.";
return 0;
}
int vowelCheck(std::string a)
{using namespace std;
string exceptions = "aeiouAEIOU";
string vowels;
string *cPtrI = &a;
string *cPtrJ = &exceptions;
for(int i = 0; i < a.size(); i++){
cout << i <<"i\n";
for(int j = 0; j < 10; j++){
cout << j << "j\n";
// cout << cPtrJ[j];
if(cPtrI[i] == cPtrJ[j]){ //if index of A equal index of J then
cout << "Added: " << cPtrJ[j];
vowels.append(cPtrJ[j]); // append that vowel to the string 'vowels'
break;
}
}
}
return vowels.size();
}
Using my debug tools listed above, the program will only increment through j = 8 then stops. Also, if I even enter an initial string something like AEIOU, it will string go through j = 8. So, it is not seeing the equivalent characters.
What am I doing wrong using strings?
Forget about pointers.
string *cPtrI = &a;
string *cPtrJ = &exceptions;
// ...
if(cPtrI[i] == cPtrJ[j]){ //if index of A equal index of J then
cPtrI[i] is the same as *(cPtrI + i), which would be indexing into an array of string.
That's why cPtrI[i] == 'a' doesn't compile. cPtrI[i] has type std::string& (remember, it's indexing into a non-existing array of std::string), and 'a' is a char. You can't compare the two.
std::string has an indexing operator of its own. Just don't use pointless pointers and it just works.
if(a[i] == exceptions[j]){
You appear to be counting the number of vowels in a string. Instead of writing out the for loops manually and building up a string, let's use count_if to do that. The plan is to create a function object that can detect if a character is a vowel and then use count_if to count the number of vowel characters in the string:
struct VowelFinder
{
bool operator()(char c)
{
std::string vowels = "aeiouAEIOU";
return vowels.find(c) != std::string::npos;
}
};
int vowelCheck(const std::string& a)
{
return std::count_if(a.begin(), a.end(), VowelFinder());
}
I've answered your C-related questions in comments.
As for your usage of std::string, you're actually trying to use std::string* for some reason. Don't do that. Just use the std::string; operator [] is overloaded for it to work as-is. At the moment you're treating cPtrI as a element of an array of strings.