View previous topic :: View next topic |
Author |
Message |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Mar 17, 2011 6:42 pm Post subject: [C++] Scrambling a sentence |
|
|
Basically, I want to accomplish this:
input: Hello there my name is joe and I am 30.
output: name there my I 30 am Hello and joe.
I'm trying to make a sentance scrambler, but I have tried multiple methods involving double arrays, vectors, etc, and all attempts have gone to shit.
Whats the easiest way to do this?
_________________
|
|
Back to top |
|
 |
HomerSexual Grandmaster Cheater Supreme
Reputation: 5
Joined: 03 Feb 2007 Posts: 1657
|
Posted: Thu Mar 17, 2011 7:04 pm Post subject: |
|
|
I would use string splitting to make an array of Strings (each a word)
http://stackoverflow.com/questions/236129/how-to-split-a-string
See that link on how to use string splitting in c++ (I code in Java so no help there)
Then make a randomize method that will swap values in the array based on the selection of two random values in range [0,n-1]. In order to swap in an array, you must use a temporary buffer to not overwrite ex:
String s = arr[to];
arr[to] = arr[from]
arr[from] = s
Make sense? I could code it in Java if need be, probably c++ also if really need be
edit bored, here's some java code:
Code: | import java.util.Scanner;
public class Scrambler
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
while(in.hasNextLine())
{
String line = in.nextLine();
String[] splitString = line.split(" ");
randomize(splitString);
for(int i = 0; i < splitString.length; i++)
System.out.print(splitString[i] + " ");
}
}
/**
* Randomizes arr to some extent
* @param arr
*/
public static void randomize(String[] arr)
{
for(int i = 0; i < 1000; i++)
{
int randomFrom = (int)(Math.random() * arr.length);
int randomTo = (int)(Math.random() * arr.length);
swap(arr, randomFrom, randomTo);
}
}
/**
* Swaps two positions in an array
* @param arr The array of String
* @param from First position to swap
* @param to Second position to swap
*/
public static void swap(String[] arr, int from, int to)
{
String temp = arr[from];
arr[from] = arr[to];
arr[to] = temp;
}
}
|
_________________
|
|
Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Mar 17, 2011 9:13 pm Post subject: |
|
|
I'd rather not use the sstream. Basically, I was just wondering what the best way would be to parse and store the input, I can handle the output after that.
_________________
Last edited by manc on Thu Mar 17, 2011 9:33 pm; edited 1 time in total |
|
Back to top |
|
 |
AhMunRa Grandmaster Cheater Supreme
Reputation: 27
Joined: 06 Aug 2010 Posts: 1117
|
Posted: Thu Mar 17, 2011 9:18 pm Post subject: |
|
|
I would agree with Homer, if I were doing it. I'd split the string on " " and store into an array then use a rand() to copy elements back into a 2nd array then print, or bypass the 2nd array and just print.
_________________
<Wiccaan> Bah that was supposed to say 'not saying its dead' lol. Fixing >.> |
|
Back to top |
|
 |
manc Grandmaster Cheater
Reputation: 1
Joined: 16 Jun 2006 Posts: 551
|
Posted: Thu Mar 17, 2011 9:52 pm Post subject: |
|
|
AhMunRa wrote: | I'd split the string on " " and store into an array |
This is really the only part I need help with I guess. I tried using a double array, but I didnt know how big to make it, and the compiler wouldnt let me make it dynamic, I tried finding out the necessary size of my array by counting the amount of spaces in the sentence, but still, the compiler demanded a constant value. Then I tried to bypass that by using vectors...
Code: |
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
string input;
cout << "Input string: ";
getline(cin, input);
vector<string> myVec;
int j = 0;
for(int i=0; i<input.size(); i++){
if( input[i] == ' '){
myVec.push_back(input.substr(j,i));
j = i+1;
}
}
return 0;
} |
Everything I'm doing is failing though ._.
_________________
|
|
Back to top |
|
 |
Deltron Z Expert Cheater
Reputation: 1
Joined: 14 Jun 2009 Posts: 164
|
Posted: Thu Mar 17, 2011 11:18 pm Post subject: |
|
|
Code: | #include <list>
#include <stdlib.h>
#include <time.h>
int main()
{
char* sentence = "scramble this sentence with many words please";
char copy[100];
std::list<char*> words;
srand(time(0));
strcpy_s(copy, sentence);
char* temp = copy;
for (int i = 0; copy[i]; i++)
{
if (copy[i] == ' ')
{
copy[i] = 0;
if (rand() & 1)
words.push_back(temp);
else
words.push_front(temp);
temp = ©[i + 1];
}
}
for (std::list<char*>::iterator i = words.begin(); i != words.end(); i++)
printf("%s ", *i);
return 0;
} |
First - I copied the string in case you don't want to change the original one.
Then I seperates the words by replacing every space with null-char and added the word to the list randomaly either to the beginning or the end.
I used printf because I prefer printf rather than cout.
I used char* instead of string for efficiency, but you can use string too.
_________________
SharpDisassembler
"When I find my code in tons of trouble,
Friends and colleagues come to me...
Speaking words of wisdom:
Write in C."
#pragma message("Let there be byte!") |
|
Back to top |
|
 |
HomerSexual Grandmaster Cheater Supreme
Reputation: 5
Joined: 03 Feb 2007 Posts: 1657
|
Posted: Fri Mar 18, 2011 1:50 pm Post subject: |
|
|
manc wrote: | AhMunRa wrote: | I'd split the string on " " and store into an array |
This is really the only part I need help with I guess. I tried using a double array, but I didnt know how big to make it, and the compiler wouldnt let me make it dynamic, I tried finding out the necessary size of my array by counting the amount of spaces in the sentence, but still, the compiler demanded a constant value. Then I tried to bypass that by using vectors...
Code: |
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main(){
string input;
cout << "Input string: ";
getline(cin, input);
vector<string> myVec;
int j = 0;
for(int i=0; i<input.size(); i++){
if( input[i] == ' '){
myVec.push_back(input.substr(j,i));
j = i+1;
}
}
return 0;
} |
Everything I'm doing is failing though ._. |
Why are you trying to reinvent the wheel? You're using c++ so make use of the library it gives you. Also, are vectors thread-safe in c++ (they are in Java). If so, you are giving up performance for no reason whatsoever.
I gave you all the answers you need.
Code: | import java.util.*;
public class StringTokens
{
public static void main(String[] args)
{
String input;
Scanner in = new Scanner(System.in);
//same as getline in your code
input = in.nextLine();
//I would not use Vectors for this as there is unnecessary overhead
Vector<String> myVec = new Vector<String>();
int j = 0;
for(int i = 0; i < input.length(); i++)
{
if(input.charAt(i) == ' ')
{
myVec.add(((String) input.subSequence(j, i)).trim());
j = i;
}
}
//myVec now contains the sentence broken up (with no white space trailing or leading)
}
}
|
There is the Java implementation of tokenizing a string by ' ' manually. If you can't convert THAT to c++ code, you should probably not be coding
_________________
|
|
Back to top |
|
 |
|