Boyer Moore dynamic array implementation - c++

Im trying to implement the Boyer Moore(bad character heuristic) algorithm, except i want to use a dynamic array. Can anyone help me with this problem? here's my source code.
**/* Program for Bad Character Heuristic of Boyer Moore String Matching Algorithm */
# include <limits.h>
# include <string.h>
# include <stdio.h>
# define NO_OF_CHARS 256
/* Driver program to test above funtion */
int main()
{
char txt[];
char pat[];
ifstream myfile;
string filename;
cout<<"input file"<<endl;
getline(cin, filename);
myfile.open(filename.c_str());
if(myfile.is_open()){
cout<<"file not found"<<endl;
while(getline(myfile, txt))
{
cout<<txt<<endl;
}
cout<<"pls input pattern"<<endl;
cin.getline(pat[]);
search(txt, pat);
myfile.close();
}
else cout<<"file not found"<<endl:
return 0;
}**

std::string is exactly what you would need in this case. It is dynamic in size (as in it is sized appropriately when read into). Just be sure to pass the char* pointer part when necessary using the c_str() member function.

I did that like couple of days ago, if you still need the answer... Just declare a dynamic char array and pass it to the function.
Here char str parameter can take a dynamic char array, and with your badchar[NO_OF_CHARS] array you can implement bad character heuristic before you use search function.
void badCharHeuristic(char *str, int badchar[NO_OF_CHARS])
{
int size = strlen(str);
int i;
for (i = 0; i < NO_OF_CHARS; i++)
badchar[i] = -1;
for (i = 0; i < size; i++)
badchar[str[i]] = i;
}
Also your search function should be something like that:
void search(char *txt, char *pat)
{
int s = 0; // s is the variable that hold how many shift we are gonna make
while (s <= (n - m))
{
int j = m - 1;
while (j >= 0 && pat[j] == txt[s + j])
j--;
if (j < 0)
{
printf("pattern occurs at shift = %d ", s);
s += (s + m < n) ? m - badchar[txt[s + m]] : 1; //if s+m < n; s = m - badchar[txt[s + m] else; s = 1
}
else
s += max(1, j - badchar[txt[s + j]]);
}
}

Related

What's wrong with my dynamic programming algorithm with memoization?

*Sorry about my poor English. If there is anything that you don't understand, please tell me so that I can give you more information that 'make sence'.
**This is first time asking question in Stackoverflow. I've searched some rules for asking questions correctly here, but there should be something I missed. I welcome all feedback.
I'm currently solving algorithm problems to improve my skill, and I'm struggling with one question for three days. This question is from https://algospot.com/judge/problem/read/RESTORE , but since this page is in KOREAN, I tried to translate it in English.
Question
If there are 'k' pieces of partial strings given, calculate shortest string that includes all partial strings.
All strings consist only lowercase alphabets.
If there are more than 1 result strings that satisfy all conditions with same length, choose any string.
Input
In the first line of input, number of test case 'C'(C<=50) is given.
For each test case, number of partial string 'k'(1<=k<=15) is given in the first line, and in next k lines partial strings are given.
Length of partial string is between 1 to 40.
Output
For each testcase, print shortest string that includes all partial strings.
Sample Input
3
3
geo
oji
jing
2
world
hello
3
abrac
cadabra
dabr
Sample Output
geojing
helloworld
cadabrac
And here is my code. My code seems to work perfect with Sample Inputs, and when I made test inputs for my own and tested, everything worked fine. But when I submit this code, they say my code is 'wrong'.
Please tell me what is wrong with my code. You don't need to tell me whole fixed code, I just need sample inputs that causes error with my code. Added code description to make my code easier to understand.
Code Description
Saved all input partial strings in vector 'stringParts'.
Saved current shortest string result in global variable 'answer'.
Used 'cache' array for memoization - to skip repeated function call.
Algorithm I designed to solve this problem is divided into two function -
restore() & eraseOverlapped().
restore() function calculates shortest string that includes all partial strings in 'stringParts'.
Result of resotre() is saved in 'answer'.
For restore(), there are three parameters - 'curString', 'selected' and 'last'.
'curString' stands for currently selected and overlapped string result.
'selected' stands for currently selected elements of 'stringParts'. Used bitmask to make my algorithm concise.
'last' stands for last selected element of 'stringParts' for making 'curString'.
eraseOverlapped() function does preprocessing - it deletes elements of 'stringParts' that can be completly included to other elements before executing restore().
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
string answer; // save shortest result string
vector<string> stringParts;
bool cache[MAX + 1][(1 << MAX) + 1]; //[last selected string][set of selected strings in Bitmask]
void restore(string curString, int selected=0, int last=0) {
//base case 1
if (selected == (1 << k) - 1) {
if (answer.empty() || curString.length() < answer.length())
answer = curString;
return;
}
//base case 2 - memoization
bool& ret = cache[last][selected];
if (ret != false) return;
for (int next = 0; next < k; next++) {
string checkStr = stringParts[next];
if (selected & (1 << next)) continue;
if (curString.empty())
restore(checkStr, selected + (1 << next), next + 1);
else {
int check = false;
//count max overlapping area of two strings and overlap two strings.
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size()-i, i) == checkStr.substr(0, i)) {
restore(curString + checkStr.substr(i, checkStr.length()-i), selected + (1 << next), next + 1);
check = true;
break;
}
}
if (!check) { // if there aren't any overlapping area
restore(curString + checkStr, selected + (1 << next), next + 1);
}
}
}
ret = true;
}
//check if there are strings that can be completely included by other strings, and delete that string.
void eraseOverlapped() {
//arranging string vector in ascending order of string length
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
//deleting included strings
vector<string>::iterator iter;
for (int i = 0; i < vectorLen-1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C; // testcase
for (int testCase = 0; testCase < C; testCase++) {
cin >> k; // number of partial strings
memset(cache, false, sizeof(cache)); // initializing cache to false
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
eraseOverlapped();
k = stringParts.size();
restore("");
cout << answer << endl;
answer.clear();
stringParts.clear();
}
}
After determining which string-parts can be removed from the list since they are contained in other string-parts, one way to model this problem might be as the "taxicab ripoff problem" problem (or Max TSP), where each potential length reduction by overlap is given a positive weight. Considering that the input size in the question is very small, it seems likely that they expect a near brute-force solution, with possibly some heuristic and backtracking or other form of memoization.
Thanks Everyone who tried to help me solve this problem. I actually solved this problem with few changes on my previous algorithm. These are main changes.
In my previous algorithm I saved result of restore() in global variable 'answer' since restore() didn't return anything, but in new algorithm since restore() returns mid-process answer string I no longer need to use 'answer'.
Used string type cache instead of bool type cache. I found out using bool cache for memoization in this algorithm was useless.
Deleted 'curString' parameter from restore(). Since what we only need during recursive call is one previously selected partial string, 'last' can replace role of 'curString'.
CODE
#include <algorithm>
#include <iostream>
#include <vector>
#include <cstring>
#include <string>
#define MAX 15
using namespace std;
int k;
vector<string> stringParts;
string cache[MAX + 1][(1 << MAX) + 1];
string restore(int selected = 0, int last = -1) {
if (selected == (1 << k) - 1) {
return stringParts[last];
}
if (last == -1) {
string ret = "";
for (int next = 0; next < k; next++) {
string resultStr = restore(selected + (1 << next), next);
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
string& ret = cache[last][selected];
if (!ret.empty()) {
cout << "cache used in [" << last << "][" << selected << "]" << endl;
return ret;
}
string curString = stringParts[last];
for (int next = 0; next < k; next++) {
if (selected & (1 << next)) continue;
string checkStr = restore(selected + (1 << next), next);
int check = false;
string resultStr;
for (int i = (checkStr.length() > curString.length() ? curString.length() : checkStr.length())
; i > 0; i--) {
if (curString.substr(curString.size() - i, i) == checkStr.substr(0, i)) {
resultStr = curString + checkStr.substr(i, checkStr.length() - i);
check = true;
break;
}
}
if (!check)
resultStr = curString + checkStr;
if (ret.empty() || ret.length() > resultStr.length())
ret = resultStr;
}
return ret;
}
void EraseOverlapped() {
int vectorLen = stringParts.size();
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].length() < stringParts[j].length()) {
string temp = stringParts[i];
stringParts[i] = stringParts[j];
stringParts[j] = temp;
}
}
}
vector<string>::iterator iter;
for (int i = 0; i < vectorLen - 1; i++) {
for (int j = i + 1; j < vectorLen; j++) {
if (stringParts[i].find(stringParts[j]) != string::npos) {
iter = stringParts.begin() + j;
stringParts.erase(iter);
j--;
vectorLen--;
}
}
}
}
int main(void) {
int C;
cin >> C;
for (int testCase = 0; testCase < C; testCase++) {
cin >> k;
for (int i = 0; i < MAX + 1; i++) {
for (int j = 0; j < (1 << MAX) + 1; j++)
cache[i][j] = "";
}
string inputStr;
for (int i = 0; i < k; i++) {
cin >> inputStr;
stringParts.push_back(inputStr);
}
EraseOverlapped();
k = stringParts.size();
string resultStr = restore();
cout << resultStr << endl;
stringParts.clear();
}
}
This algorithm is much slower than the 'ideal' algorithm that the book I'm studying suggests, but it was fast enough to pass this question's time limit.

Runtime error when I run the program but not when i use debugger

I'm trying to make a c/c++ program where the program accepts a txt file with several words, one per line, and finds the edit distance(also called levenshtein distance) with a specific word.
I have a weird problem.
My code encounters a runtime error after a reading a couple of words when I run it in code-blocks. It debugs fine when i use the code-blocks debugger.
I have been looking around and I found uninitialised variables can be a problem. But whenever i comment the line where i am calling the function minDistance count[i]=minDistance(word,lines[i]);, the code runs fine and prints out all the words in the file. So that's not a problem I guess.
Any help would be great. Thank you.
Following is the code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include<iostream>
using namespace std;
static int minDistance(char* word1, char* word2)
{
const int l1 = strlen(word1);
const int l2 = strlen(word2);
int i=0,j=0;
int **d = new int*[l2 + 1];
for(i=0;i<l1+1;++i)
d[i]=new int[l1+1];
// the edit distance between an empty string and the prefixes of
// word2
for (i = 0; i < l2 + 1; i++) {
d[0][i] = i;
}
// the edit distance between an empty string and the prefixes of
// word1
for (j = 0; j < l1 + 1; j++) {
d[j][0] = j;
}
for (i = 1; i < l1 + 1; i++) {
for (j = 1; j < l2 + 1; j++) {
if (word1[i - 1] == word2[j - 1]) {
d[i][j] = d[i - 1][j - 1];
} else {
d[i][j] = min(min(1 + d[i][j - 1], 1 + d[i - 1][j]),
1 + d[i - 1][j - 1]); // min of insertion,
// deletion, replacement
}
}
}
return d[l1][l2];
}
void lines()
{
int i=0;
char * lines[10];
int count[10];
char word[]="book";
FILE *file_handle = fopen ("wordlist.txt", "r");
for (i =0; i < 5; ++i)
{
lines[i] = (char*)malloc (128); /* allocating a memory slot of 128 chars */
fscanf (file_handle, "%s", lines[i]);
count[i]=minDistance(word,lines[i]);
cout<<lines[i]<<" ";
cout<<count[i]<<endl;
}
for (i =0; i < 5; ++i)
free (lines[i]);
}
int main (int argc, char *argv[])
{
lines();
return 0;
}
Notice the lines in your code :
int **d = new int*[l2 + 1];
for(i=0;i<l1+1;++i)
You are allocating memory for (l2 + 1) number of int* and you are looping i from 0 to (l1 + 1). So if l2 < l1, you are accessing memory you have not allocated.
Also don't mix C++ and C. Either use C or stick with C++. As mentioned in the comments, if you can use C++, use std::vector and std::string - it will reduce your headache. Also use C++'s IO classes to perform File IO and always close any file you have opened. (i.e. in C, use fclose(file_ptr) ).
You use l2 as your second index. It should be your first index and l1 your second index.
// the edit distance between an empty string and the prefixes of
// word2
for (i = 0; i < l1 + 1; i++) {
d[0][i] = i;
}

converting a string (containing numbers) into an integer and returning that integer

i'm working on a code right now in C++, in which i'm supposed to make a function which receives a string of numbers and converts it into an integer then returns that value. for example if i pass "4569" as string, it will return 4569 integer value.
can anyone help me point out where i'm wrong ??? thanks in advance :)
#include<iostream>
#include<cstdlib>
using namespace std;
void getInput(char arr[] , int size )
{
cout<<"ENTER THE ARRAY"<<endl;
cin.getline(arr,size);
}
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for( int i=y ; i>=0 ; i--)
{
int n= source[i];
sum = (sum + (n * multiply));
multiply = (multiply *10);
}
return sum;
}
int main()
{
const int size =100;
char inputArr [size];
getInput (inputArr, size );
int x = stringToInteger (inputArr );
cout<<"THE RETURNED INTEGER VALUE IS"<<endl;
cout<<x<<endl;
return 0;
}
First, you're starting at the character after the end of the string. If the length (returned by strlen) is y, then valid indexes are 0 <= i < y. So your loop wants to start from y-1.
for( int i=y-1 ; i>=0 ; i--)
^^
Then, you need to convert each ASCII digit into a value from 0 to 9, by subtracting the ASCII value for '0':
int n= source[i] - '0';
^^^^^
Then you should probably detect and handle erroneous input, including values that are too large to be represented by int.
Then, once you've learnt how to implement this in C, throw it away and use the C++ library:
std::string input;
std::getline(std::cin, input);
int x = std::stoi(input);
Try,
#include <stdlib.h>
and in your main():
int x = atoi(inputArr);
I'm not sure why you aren't using atoi or std::stoi, but your algorithm has a logical flaw:
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for(int i=y - 1; i >= 0; i--) // you were starting at y, which is 1 passed the end of the array
{
int n = (int)(source[i] - '0');
sum += (n * multiply); // += makes this more readable
multiply *= 10; // same with *=
}
return sum;
}
That said, if this was something other than a homework assignment, you should be using the solutions posted https://stackoverflow.com/a/18238566/529761 or https://stackoverflow.com/a/18238682/529761 (depending on your language requirements).
Also, even this change has 1 potential problem: If the source contains non-numeric characters, it will not work properly. A simple way to approach it is to break out if you encounter a character that shouldn't be there:
int stringToInteger(char source[])
{
int sum = 0;
int y=strlen(source);
int multiply = 1;
for(int i=y - 1; i >= 0; i--) // you were starting at y, which is 1 passed the end of the array
{
int n = (int)(source[i] - '0');
if (n < 0 || n > 9)
break;
sum += (n * multiply); // += makes this more readable
multiply *= 10; // same with *=
}
return sum;
}
No need to call a strlen -- until you are allowed to use library functions (the above-mentioned atoi and strtol), you can use this:
int stringToInteger(char *source)
{
int sum = 0;
if (source)
while (*source >= '0' && *source <= '9')
{
sum = 10*sum + *source - '0';
source++;
}
return sum;
}
As implied in about every other answer, you forgot there is a difference between the ASCII character '0' and the binary value 0.

Find subsequence of given length from a given string?

To find the sub-sequences from a string of given length i have a recursive code (shown below) but it takes much time when the string length is big....
void F(int index, int length, string str)
{
if (length == 0) {
cout<<str<<endl;
//int l2=str.length();
//sum=0;
//for(int j=0;j<l2;j++)
//sum+=(str[j]-48);
//if(sum%9==0 && sum!=0)
//{c++;}
//sum=0;
} else {
for (int i = index; i < n; i++) {
string temp = str;
temp += S[i];
//sum+=(temp[i]-48);
F(i + 1, length - 1, temp);
}
}
}
Please help me with some idea of implementing non-recursive code or something else.
You mentioned your current code is too slow when the input string length is large. It would be helpful if you could provide a specific example along with your timing info so we know what you consider to be "too slow". You should also specify what you would consider to be an acceptable run time. Here's an example:
I'll start with an initial version that I believe is similar to your current algorithm. It generates all subsequences of length >= 2:
#include <iostream>
#include <string>
void subsequences(const std::string& prefix, const std::string& suffix)
{
if (prefix.length() >= 2)
std::cout << prefix << std::endl;
for (size_t i=0; i < suffix.length(); ++i)
subsequences(prefix + suffix[i], suffix.substr(i + 1));
}
int main(int argc, char* argv[])
{
subsequences("", "ABCD");
}
Running this program produces the following output:
AB
ABC
ABCD
ABD
AC
ACD
AD
BC
BCD
BD
CD
Now let's change the input string to something longer. I'll use a 26-character input string:
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
This generates 67,108,837 subsequences. I won't list them here :-). On my machine, the code shown above takes just over 78 seconds to run (excluding output to cout) with the 26-character input string.
When I look for ways to optimize the above code, one thing that jumps out is that it's creating two new string objects for each recursive call to subsequences(). What if we could preallocate space once upfront and then simply pass pointers? Version 2:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
void subsequences(char* prefix, int prefixLength, const char* suffix)
{
if (prefixLength >= 2)
printf("%s\n", prefix);
for (size_t i=0; i < strlen(suffix); ++i) {
prefix[prefixLength] = suffix[i];
prefix[prefixLength + 1] = '\0';
subsequences(prefix, prefixLength + 1, suffix + i + 1);
}
}
int main(int argc, char* argv[])
{
const char *inputString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *prefix = (char*) _malloca(strlen(inputString) + 1);
subsequences(prefix, 0, inputString);
}
This generates the same 67,108,837 subsequences, but execution time is now just over 2 seconds (again, excluding output via printf).
Your code might be slow because your string is large. For a sequence of n unique elements there are (n over k) subsequences of length k. That means for the sequence "ABCDEFGHIJKLMNOPQRSTUVWXYZ" there are 10.400.600 different subsequences of length 13. That number grows pretty fast.
Nevertheless, since you asked, here is a non-recursive function that takes a string str and a size n and prints all subsequences of length n of that string.
void print_subsequences(const std::string& str, size_t n)
{
if (n < 1 || str.size() < n)
{
return; // there are no subsequences of the given size
}
// start with the first n characters (indexes 0..n-1)
std::vector<size_t> indexes(n);
for (size_t i = 0; i < n; ++i)
{
indexes[i] = i;
}
while (true)
{
// build subsequence from indexes
std::string subsequence(n, ' ');
for (size_t i = 0; i < n; ++i)
{
subsequence[i] = str[indexes[i]];
}
// there you are
std::cout << subsequence << std::endl;
// the last subsequence starts with n-th last character
if (indexes[0] >= str.size() - n)
{
break;
}
// find rightmost incrementable index
size_t i = n;
while (i-- > 0)
{
if (indexes[i] < str.size() - n + i)
{
break;
}
}
// increment that index and set all following indexes
size_t value = indexes[i];
for (; i < n; ++i)
{
indexes[i] = ++value;
}
}
}

remove commas from string

I created a program in C++ that remove commas (,) from a given integer. i.e. 2,00,00 would return 20000. I am not using any new space. Here is the program I created:
void removeCommas(string& str1, int len)
{
int j = 0;
for (int i = 0; i < len; i++)
{
if (str1[i] == ',')
{
continue;
}
else
{
str1[j] = str1[i];
j++;
}
}
str1[j] = '\0';
}
void main()
{
string str1;
getline(cin, str1);
int i = str1.length();
removeCommas(str1, i);
cout << "the new string " << str1 << endl;
}
Here is the result I get:
Input : 2,000,00
String length =8
Output = 200000 0
Length = 8
My question is that why does it show the length has 8 in output and shows the rest of string when I did put a null character. It should show output as 200000 and length has 6.
Let the standard library do the work for you:
#include <algorithm>
str1.erase(std::remove(str1.begin(), str1.end(), ','), str1.end());
If you don't want to modify the original string, that's easy too:
std::string str2(str1.size(), '0');
str2.erase(std::remove_copy(str1.begin(), str1.end(), str2.begin(), ','), str2.end());
You need to do a resize instead at the end.
Contrary to popular belief an std::string CAN contain binary data including 0s. An std::string 's .size() is not related to the string containing a NULL termination.
std::string s("\0\0", 2);
assert(s.size() == 2);
The answer is probably that std::strings aren't NUL-terminated. Instead of setting the end+1'th character to '\0', you should use str.resize(new_length);.
Edit: Also consider that, if your source string has no commas in it, then your '\0' will be written one past the end of the string (which will probably just happen to work, but is incorrect).
The std::srting does not terminate with \0, you are mixing this with char* in C. So you should use resize.
The solution has already been posted by Fred L.
In a "procedural fashion" (without "algorithm")
your program would look like:
void removeStuff(string& str, char character)
{
size_t pos;
while( (pos=str.find(character)) != string::npos )
str.erase(pos, 1);
}
void main()
{
string str1;
getline(cin, str1);
removeStuff(str1, ',');
cout<<"the new string "<<str1<<endl;
}
then.
Regards
rbo
EDIT / Addendum:
In order to adress some efficiency concerns of readers,
I tried to come up with the fastest solution possible.
Of course, this should kick in on string sizes over
about 10^5 characters with some characters to-be-removed
included:
void fastRemoveStuff(string& str, char character)
{
size_t len = str.length();
char *t, *buffer = new char[len];
const char *p, *q;
t = buffer, p = q = str.data();
while( p=(const char*)memchr(q, character, len-(p-q)) ) {
memcpy(t, q, p-q);
t += p-q, q = p+1;
}
if( q-str.data() != len ) {
size_t tail = len - (q-str.data());
memcpy(t, q, tail);
t += tail;
}
str.assign(buffer, t-buffer);
delete [] buffer;
}
void main()
{
string str1 = "56,4,44,55,5,55"; // should be large, 10^6 is good
// getline(cin, str1);
cout<<"the old string " << str1 << endl;
fastRemoveStuff(str1, ',');
cout<<"the new string " << str1 << endl;
}
My own procedural version:
#include <string>
#include <cassert>
using namespace std;
string Remove( const string & s, char c ) {
string r;
r.reserve( s.size() );
for ( unsigned int i = 0; i < s.size(); i++ ) {
if ( s[i] != c ) {
r += s[i];
}
}
return r;
}
int main() {
assert( Remove( "Foo,Bar,Zod", ',' ) == "FooBarZod" );
}
Here is the program:
void main()
{
int i ;
char n[20] ;
clrscr() ;
printf("Enter a number. ") ;
gets(n) ;
printf("Number without comma is:") ;
for(i=0 ; n[i]!='\0' ; i++)
if(n[i] != ',')
putchar(n[i]) ;
getch();
}
For detailed description you can refer this blog: http://tutorialsschool.com/c-programming/c-programs/remove-comma-from-string.php
The same has been discussed in this post: How to remove commas from a string in C
Well, if youre planing to read from a file using c++. I found a method, while I dont think thats the best method though, but after I came to these forums to search for help before, I think its time to contribute with my effort aswell.
Look, here is the catch, what I'm going to present you is part of the source code of the map editor Im building on right now, that map editor obviously has the purpose to create maps for a 2D RPG game, the same style as the classic Pokemon games for example. But this code was more towards the development of the world map editor.
`int strStartPos = 0;
int strSize = 0;
int arrayPointInfoDepth = 0;
for (int x = 0; x < (m_wMapWidth / (TileSize / 2)); x++) {
for (int y = 0; y < (m_wMapHeight / (TileSize / 2)); y++) {
if (ss >> str) {
for (int strIterator = 0; strIterator < str.length(); strIterator++) {
if (str[strIterator] == ',') {`
Here we need to define the size of the string we want to extract after the previous comma and before the next comma
`strSize = strIterator - strStartPos;`
And here, we do the actual transformation, we give to the vector that is a 3D vector btw the string we want to extract at that moment
`m_wMapPointInfo[x][y][arrayPointInfoDepth] = str.substr(strStartPos, strSize);`
And here, we just define that starting position for the next small piece of the string we want to extract, so the +1 means that after the comma we just passed
strStartPos = strIterator + 1;
Here, well since my vector has only 6 postions that is defined by WorldMapPointInfos we need to increment the third dimension of the array and finally do a check point where if the info has arrived the number 6 then break the loop
arrayPointInfoDepth++;
if (arrayPointInfoDepth == WorldMapPointInfos) {
strStartPos = 0;
arrayPointInfoDepth = 0;
break;
}
}
}
}
}
}
Either way on my code, think abt that the vector is just a string, thats all you need to know, hope this helps though :/
Full view:
int strStartPos = 0;
int strSize = 0;
int arrayPointInfoDepth = 0;
for (int x = 0; x < (m_wMapWidth / (TileSize / 2)); x++) {
for (int y = 0; y < (m_wMapHeight / (TileSize / 2)); y++) {
if (ss >> str) {
for (int strIterator = 0; strIterator < str.length(); strIterator++) {
if (str[strIterator] == ',') {
strSize = strIterator - strStartPos;
m_wMapPointInfo[x][y][arrayPointInfoDepth] = str.substr(strStartPos, strSize);
strStartPos = strIterator + 1;
arrayPointInfoDepth++;
if (arrayPointInfoDepth == WorldMapPointInfos) {
strStartPos = 0;
arrayPointInfoDepth = 0;
break;
}
}
}
}
}
}