Remove duplicate string elements C++ - string

The problem consists of finding all permutations using k out of n digits. I'm able to find all the permutations, but I'm struggling trying to erase duplicates. I can successfully compare and find the duplicates, but erasing them is what I'm struggling to do. I have a feeling I'm missing something simple but I don't know what it is.
Any help would be greatly appreciated. I've been staring at this for a week.
Here is the code that I've got right now.
void getPermutations(int n, int k)
{
string str = "";
//fill string with numbers <= n
for(int i = 0; i < n; i++)
{
str += to_string(i); //convert numbers to string
}
string tempStr = "";
string outputStr = "";
do {
tempStr = str.substr(0, k);
int compareResult = tempStr.compare(0, k, outputStr, 0, k);
if (compareResult == 0)
{
cout << "| same | ";
outputStr.erase(k,k);
}
outputStr = tempStr;
cout << outputStr << " ";
} while (next_permutation(str.begin(), str.end()));
}

I think what you meant to do was to erase the contents of tempStr, not outputStr.
The call to erase is not exactly right. Its first argument marks the starting position of your erasing, and the second argument tells how many characters to erase. So if you want to erase the whole string, the first argument should be...
You actually don't have to erase anything. After you get it working your way, try to do it without erasing!
Good Luck!

Related

Code for creating string in a loop to report numbers

I created a code that functions as it is supposed to. I determined the escape function to be -1 for the user to exit the program and used if/else to only add the sum of positive integers.
I know that I have to save the numbers that pass the if statement (only positive numbers) and the only way that I can think of doing this is through a String.
Unfortunately, whenever I attempt to add a string as part of the while loop, it will print the statement over and over again when I only want a single line.
I'm also struggling to set the user input to a single line. I know it has everything to do with the .nextLine() command, but if I pull it outside the brackets (which I've attempted to do) then it reads as an error.
Actually, a source about conversion of Strings to characters or inputs to Strings would be very helpful as well. It's apparent that this is where a good portion of my understanding is lacking.
public static void main(String args[])
{
int userNum = 0;
int sum = 0;
Scanner s = new Scanner(System.in);
String str3;
System.out.print("Enter positive integers (to exit enter -1):\n ");
//Loop for adding sum with exit -1
while(userNum != -1){
//condition to only calculate positive numbers user entered
if(userNum > 0){
//calculation of all positive numbers user entered
sum += userNum;
str3 = String.valueOf(userNum);}
userNum = s.nextInt();
}
System.out.println("The values of the sum are: " + str3);
System.out.println("The Sum: " + sum);
}
}
I'm hoping for the user input to be printed,
Enter positive integers (to exit enter -1): _ _ ___//with the user
input in the same row.
And...
values from string to read out on same line, not multiple lines.
The variable str needs to be initialized as:
String str3 = "";
and in the loop, each entered number must be concatenated to str.
int userNum = 0;
int sum = 0;
Scanner s = new Scanner(System.in);
String str3 = "";
System.out.print("Enter positive integers (to exit enter -1):\n ");
while (userNum != -1) {
userNum = s.nextInt();
if (userNum > 0) {
sum += userNum;
str3 += " " + userNum;
}
}
System.out.println("The values of the sum are: " + str3);
System.out.println("The Sum: " + sum);

Finding minimum moves required for making 2 strings equal

This is a question from one of the online coding challenge (which has completed).
I just need some logic for this as to how to approach.
Problem Statement:
We have two strings A and B with the same super set of characters. We need to change these strings to obtain two equal strings. In each move we can perform one of the following operations:
1. swap two consecutive characters of a string
2. swap the first and the last characters of a string
A move can be performed on either string.
What is the minimum number of moves that we need in order to obtain two equal strings?
Input Format and Constraints:
The first and the second line of the input contains two strings A and B. It is guaranteed that the superset their characters are equal.
1 <= length(A) = length(B) <= 2000
All the input characters are between 'a' and 'z'
Output Format:
Print the minimum number of moves to the only line of the output
Sample input:
aab
baa
Sample output:
1
Explanation:
Swap the first and last character of the string aab to convert it to baa. The two strings are now equal.
EDIT : Here is my first try, but I'm getting wrong output. Can someone guide me what is wrong in my approach.
int minStringMoves(char* a, char* b) {
int length, pos, i, j, moves=0;
char *ptr;
length = strlen(a);
for(i=0;i<length;i++) {
// Find the first occurrence of b[i] in a
ptr = strchr(a,b[i]);
pos = ptr - a;
// If its the last element, swap with the first
if(i==0 && pos == length-1) {
swap(&a[0], &a[length-1]);
moves++;
}
// Else swap from current index till pos
else {
for(j=pos;j>i;j--) {
swap(&a[j],&a[j-1]);
moves++;
}
}
// If equal, break
if(strcmp(a,b) == 0)
break;
}
return moves;
}
Take a look at this example:
aaaaaaaaab
abaaaaaaaa
Your solution: 8
aaaaaaaaab -> aaaaaaaaba -> aaaaaaabaa -> aaaaaabaaa -> aaaaabaaaa ->
aaaabaaaaa -> aaabaaaaaa -> aabaaaaaaa -> abaaaaaaaa
Proper solution: 2
aaaaaaaaab -> baaaaaaaaa -> abaaaaaaaa
You should check if swapping in the other direction would give you better result.
But sometimes you will also ruin the previous part of the string. eg:
caaaaaaaab
cbaaaaaaaa
caaaaaaaab -> baaaaaaaac -> abaaaaaaac
You need another swap here to put back the 'c' to the first place.
The proper algorithm is probably even more complex, but you can see now what's wrong in your solution.
The A* algorithm might work for this problem.
The initial node will be the original string.
The goal node will be the target string.
Each child of a node will be all possible transformations of that string.
The current cost g(x) is simply the number of transformations thus far.
The heuristic h(x) is half the number of characters in the wrong position.
Since h(x) is admissible (because a single transformation can't put more than 2 characters in their correct positions), the path to the target string will give the least number of transformations possible.
However, an elementary implementation will likely be too slow. Calculating all possible transformations of a string would be rather expensive.
Note that there's a lot of similarity between a node's siblings (its parent's children) and its children. So you may be able to just calculate all transformations of the original string and, from there, simply copy and recalculate data involving changed characters.
You can use dynamic programming. Go over all swap possibilities while storing all the intermediate results along with the minimal number of steps that took you to get there. Actually, you are going to calculate the minimum number of steps for every possible target string that can be obtained by applying given rules for a number times. Once you calculate it all, you can print the minimum number of steps, which is needed to take you to the target string. Here's the sample code in JavaScript, and its usage for "aab" and "baa" examples:
function swap(str, i, j) {
var s = str.split("");
s[i] = str[j];
s[j] = str[i];
return s.join("");
}
function calcMinimumSteps(current, stepsCount)
{
if (typeof(memory[current]) !== "undefined") {
if (memory[current] > stepsCount) {
memory[current] = stepsCount;
} else if (memory[current] < stepsCount) {
stepsCount = memory[current];
}
} else {
memory[current] = stepsCount;
calcMinimumSteps(swap(current, 0, current.length-1), stepsCount+1);
for (var i = 0; i < current.length - 1; ++i) {
calcMinimumSteps(swap(current, i, i + 1), stepsCount+1);
}
}
}
var memory = {};
calcMinimumSteps("aab", 0);
alert("Minimum steps count: " + memory["baa"]);
Here is the ruby logic for this problem, copy this code in to rb file and execute.
str1 = "education" #Sample first string
str2 = "cnatdeiou" #Sample second string
moves_count = 0
no_swap = 0
count = str1.length - 1
def ends_swap(str1,str2)
str2 = swap_strings(str2,str2.length-1,0)
return str2
end
def swap_strings(str2,cp,np)
current_string = str2[cp]
new_string = str2[np]
str2[cp] = new_string
str2[np] = current_string
return str2
end
def consecutive_swap(str,current_position, target_position)
counter=0
diff = current_position > target_position ? -1 : 1
while current_position!=target_position
new_position = current_position + diff
str = swap_strings(str,current_position,new_position)
# p "-------"
# p "CP: #{current_position} NP: #{new_position} TP: #{target_position} String: #{str}"
current_position+=diff
counter+=1
end
return counter,str
end
while(str1 != str2 && count!=0)
counter = 1
if str1[-1]==str2[0]
# p "cross match"
str2 = ends_swap(str1,str2)
else
# p "No match for #{str2}-- Count: #{count}, TC: #{str1[count]}, CP: #{str2.index(str1[count])}"
str = str2[0..count]
cp = str.rindex(str1[count])
tp = count
counter, str2 = consecutive_swap(str2,cp,tp)
count-=1
end
moves_count+=counter
# p "Step: #{moves_count}"
# p str2
end
p "Total moves: #{moves_count}"
Please feel free to suggest any improvements in this code.
Try this code. Hope this will help you.
public class TwoStringIdentical {
static int lcs(String str1, String str2, int m, int n) {
int L[][] = new int[m + 1][n + 1];
int i, j;
for (i = 0; i <= m; i++) {
for (j = 0; j <= n; j++) {
if (i == 0 || j == 0)
L[i][j] = 0;
else if (str1.charAt(i - 1) == str2.charAt(j - 1))
L[i][j] = L[i - 1][j - 1] + 1;
else
L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
}
}
return L[m][n];
}
static void printMinTransformation(String str1, String str2) {
int m = str1.length();
int n = str2.length();
int len = lcs(str1, str2, m, n);
System.out.println((m - len)+(n - len));
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String str1 = scan.nextLine();
String str2 = scan.nextLine();
printMinTransformation("asdfg", "sdfg");
}
}

Remove single character occurrence from String

I want an algorithm to remove all occurrences of a given character from a string in O(n) complexity or lower? (It should be INPLACE editing original string only)
eg.
String="aadecabaaab";
removeCharacter='a'
Output:"decbb"
Enjoy algo:
j = 0
for i in length(a):
if a[i] != symbol:
a[j] = a[i]
j = j + 1
finalize:
length(a) = j
You can't do it in place with a String because it's immutable, but here's an O(n) algorithm to do it in place with a char[]:
char[] chars = "aadecabaaab".toCharArray();
char removeCharacter = 'a';
int next = 0;
for (int cur = 0; cur < chars.length; ++cur) {
if (chars[cur] != removeCharacter) {
chars[next++] = chars[cur];
}
}
// chars[0] through chars[4] will have {d, e, c, b, b} and next will be 5
System.out.println(new String(chars, 0, next));
Strictly speaking, you can't remove anything from a String because the String class is immutable. But you can construct another String that has all characters from the original String except for the "character to remove".
Create a StringBuilder. Loop through all characters in the original String. If the current character is not the character to remove, then append it to the StringBuilder. After the loop ends, convert the StringBuilder to a String.
Yep. In a linear time, iterate over String, check using .charAt() if this is a removeCharacter, don't copy it to new String. If no, copy. That's it.
This probably shouldn't have the "java" tag since in Java, a String is immutable and you can't edit it in place. For a more general case, if you have an array of characters (in any programming language) and you want to modify the array "in place" without creating another array, it's easy enough to do with two indexes. One goes through every character in the array, and the other starts at the beginning and is incremented only when you see a character that isn't removeCharacter. Since I assume this is a homework assignment, I'll leave it at that and let you figure out the details.
import java.util.*;
import java.io.*;
public class removeA{
public static void main(String[] args){
String text = "This is a test string! Wow abcdefg.";
System.out.println(text.replaceAll("a",""));
}
}
Use a hash table to hold the data you want to remove. log N complexity.
std::string toRemove = "ad";
std::map<char, int> table;
size_t maxR = toRemove.size();
for (size_t n = 0; n < maxR; ++n)
{
table[toRemove[n]] = 0;
}
Then parse the whole string and remove when you get a hit (thestring is an array):
size_t counter = 0;
while(thestring[counter] != 0)
{
std::map<char,int>::iterator iter = table.find(thestring[counter]);
if (iter == table.end()) // we found a valid character!
{
++counter;
}
else
{
// move the data - dont increment counter
memcpy(&thestring[counter], &thestring[counter+1], max-counter);
// dont increment counter
}
}
EDIT: I hope this is not a technical test or something like that. =S

I want to find the strings that repeated more than 1 times

I have an array of strings.
Some of The strings are similar (for example, person is similar to twolegperson, animal is similar to animalgold).
I want to find the strings that are repeated more than 1 times (here person,animal).
Thank you very much
faty
You need Generalized Suffix Tree. For implementations see this question.
Naive pseudocode alogrithm:
int minMatchLen = 3; // The minimum length of string match required
string stringArray[] = {"person", "twolegperson", "animal", "animalgold"}
for (i = 0; i < stringArray.length, i++) {
int strLen = stringArray[i].length;
for (substrIndex = 0; substrIndex < strLen - minMatchLen; substrIndex++) {
for (substrLen = minMatchLen; substrLen < strLen - substrIndex; substrLen++) {
string subString = stringArray[i].substr(substrIndex, substrLen);
bool matchFound = false;
for (j = i + 1; j < stringArray.length; j++) {
if stringArray[j].contains(subString) {
print("String '" + subString + "' found in '" + stringArray[j] + "'");
matchFound = true;
}
}
if (matchFound) print(""String '" + subString + "' found in '" + stringArray[i] + "'");
}
}
}
This basically goes through each string in the array, extracts all possible substrings over a specified minimum length, and then search the strings in the remainder of the array for those substrings. I'm sure there are more elegant and efficient solutions, but this will get the job done. It'll probably be slow for a large array, though.

Need a program to reverse the words in a string

I asked this question in a few interviews. I want to know from the Stackoverflow readers as to what should be the answer to this question.
Such a seemingly simple question, but has been interpreted quite a few different ways.
if your definition of a "word" is a series of non-whitespace characters surrounded by a whitespace character, then in 5 second pseudocode you do:
var words = split(inputString, " ")
var reverse = new array
var count = words.count -1
var i = 0
while count != 0
reverse[i] = words[count]
count--
i++
return reverse
If you want to take into consideration also spaces, you can do it like that:
string word = "hello my name is";
string result="";
int k=word.size();
for (int j=word.size()-1; j>=0; j--)
{
while(word[j]!= ' ' && j>=0)
j--;
int end=k;
k=j+1;
int count=0;
if (j>=0)
{
int temp=j;
while (word[temp]==' '){
count++;
temp--;
}
j-=count;
}
else j=j+1;
result+=word.substr(k,end-k);
k-=count;
while(count!=0)
{
result+=' ';
count--;
}
}
It will print out for you "is name my hello"
Taken from something called "Hacking a Google Interview" that was somewhere on my computer ... don't know from where I got it but I remember I saw this exact question inside ... here is the answer:
Reverse the string by swapping the
first character with the last
character, the second with the
second-to-last character, and so on.
Then, go through the string looking
for spaces, so that you find where
each of the words is. Reverse each of
the words you encounter by again
swapping the first character with the
last character, the second character
with the second-to-last character, and
so on.
This came up in LessThanDot Programmer Puzzles
#include<stdio.h>
void reverse_word(char *,int,int);
int main()
{
char s[80],temp;
int l,i,k;
int lower,upper;
printf("Enter the ssentence\n");
gets(s);
l=strlen(s);
printf("%d\n",l);
k=l;
for(i=0;i<l;i++)
{
if(k<=i)
{temp=s[i];
s[i]=s[l-1-i];
s[l-1-i]=temp;}
k--;
}
printf("%s\n",s);
lower=0;
upper=0;
for(i=0;;i++)
{
if(s[i]==' '||s[i]=='\0')
{upper=i-1;
reverse_word(s,lower,upper);
lower=i+1;
}
if(s[i]=='\0')
break;
}
printf("%s",s);
return 0;
}
void reverse_word(char *s,int lower,int upper)
{
char temp;
//int i;
while(upper>lower)
{
temp=s[lower];
s[lower]=s[upper];
s[upper]=temp;
upper=upper-1;
lower=lower+1;
}
}
The following code (C++) will convert a string this is a test to test a is this:
string reverseWords(string str)
{
string result = "";
vector<string> strs;
stringstream S(str);
string s;
while (S>>s)
strs.push_back(s);
reverse(strs.begin(), strs.end());
if (strs.size() > 0)
result = strs[0];
for(int i=1; i<strs.size(); i++)
result += " " + strs[i];
return result;
}
PS: it's actually a google code jam question, more info can be found here.

Resources