How to generate all variations with repetitions of a string? - c++

I want to generate all variations with repetitions of a string in C++ and I'd highly prefer a non-recursive algorithm. I've come up with a recursive algorithm in the past but due to the complexity (r^n) I'd like to see an iterative approach.
I'm quite surprised that I wasn't able to find a solution to this problem anywhere on the web or on StackOverflow.
I've come up with a Python script that does what I want as well:
import itertools
variations = itertools.product('ab', repeat=4)
for variations in variations:
variation_string = ""
for letter in variations:
variation_string += letter
print variation_string
Output:
aaaa
aaab
aaba
aabb
abaa
abab
abba
abbb
baaa
baab
baba
babb
bbaa
bbab
bbba
bbbb
Ideally I'd like a C++ program that can produce the exact output, taking the exact same parameters.
This is for learning purposes, it isn't homework. I wish my homework was like that.

You could think of it as counting, in a radix equal to the number of characters in the alphabet (taking special care of multiple equal characters in the alphabet if that's a possible input). The aaaa aaab aaba ... example for instance, is actually the binary representation of the numbers 0-15.
Just do a search on radix transformations, implement a mapping from each "digit" to corresponding character, and then simply do a for loop from 0 to word_lengthalphabet_size
Such algorithm should run in time linearly proportional to the number of strings that needs to be produced using constant amount of memory.
Demonstration in Java
public class Test {
public static void main(String... args) {
// Limit imposed by Integer.toString(int i, int radix) which is used
// for the purpose of this demo.
final String chars = "0123456789abcdefghijklmnopqrstuvwxyz";
int wordLength = 3;
char[] alphabet = { 'a', 'b', 'c' };
for (int i = 0; i < Math.pow(wordLength, alphabet.length); i++) {
String str = Integer.toString(i, alphabet.length);
String result = "";
while (result.length() + str.length() < wordLength)
result += alphabet[0];
for (char c : str.toCharArray())
result += alphabet[chars.indexOf(c)];
System.out.println(result);
}
}
}
output:
aaa
aab
aac
aba
abb
abc
aca
acb
acc
baa
bab
bac
bba
bbb
bbc
bca
bcb
bcc
caa
cab
cac
cba
cbb
cbc
cca
ccb
ccc

here is general recipe, not C++ specific to implement product:
Take product input string "abc.." to generate matrix "abc.."x"abc..". N^2 complexity.
represent matrix as vector and repeat multiplication by "abc", complexity (N^2)*N, repeat.

STL like function for next_variation. Accept iterators of any container of number like type. You can use float/doubles also.
Algorithm it self is very simple. Requirement for iterator is to be only forward. Even a std::list<...> can be used.
template<class _Tnumber, class _Titerator >
bool next_variation
(
_Titerator const& _First
, _Titerator const& _Last
, _Tnumber const& _Upper
, _Tnumber const& _Start = 0
, _Tnumber const& _Step = 1
)
{
_Titerator _Next = _First;
while( _Next != _Last )
{
*_Next += _Step;
if( *_Next < _Upper )
{
return true;
}
(*_Next) = _Start;
++_Next;
}
return false;
}
int main( int argc, char *argv[] )
{
std::string s("aaaa");
do{
std::cout << s << std::endl;
}while (next_variation(s.begin(), s.end(), 'c', 'a'));
std::vector< double > dd(3,1);
do{
std::cout << dd[0] << "," << dd[1] << "," << dd[2] << "," << std::endl;
}while( next_variation<double>( dd.begin(), dd.end(), 5, 1, 0.5 ) );
return EXIT_SUCCESS;
}

Related

Sorting a list whose items are strings of letters then number in C++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed last month.
The community reviewed whether to reopen this question last month and left it closed:
Original close reason(s) were not resolved
Improve this question
I have a list of items called "cat", "mouse" and "bird" then followed by a number (ranging from 1 to math.inf) that I want to sort.
For now I have coded this:
ui->creature_list->sortItems();
(I am working in C++ with Qt) But this sorts by string, so I have something for example like:
Mylist:
cat 1
cat 10
cat 2
cat 3
cat 4
cat 5
cat 6
cat 7
cat 8
cat 9
Here the 10 goes after the "cat 1" as it's not a number but a string. How could I solve this issue?
The sorting method that you need is called “natural sorting”. You may read here here about it.
You will find thus many answers here on SO already. The problem is that the shown solutions are rather complicated and do not explain that much.
Additionally, your solution could be solved by splitting the string in 2 parts and then comparing the number separately. But, in essence, this is, exactly, what I am doing in the below example.
Let us analyze the issue a little deeper. First, we start with the old “strcmp” algorithm.
“strcmp” compares 2 strings character by character. And the comparison is done by subtracting the characters. If characters are equal, then the result of the subtraction is 0. If one is smaller, e.g., “A” is smaller than “B”, then the result will be negative. Otherwise, positive.
If you look at the definition of the old “strcmp” function here, then you will see, that it exactly behaves as mentioned above.
So, how to approach the problems with numbers and natural sorting?
The solution is, to treat a number, consisting of one or many digits, as one entity. Then we compare these entities (the numbers formed by the digits) and continue to compare more characters after the digits (number).
Example: “cat 10 gray” and “cat 10 black”:
Compare 'C' with 'C', equal, continue
Compare 'a' with 'a', equal, continue
Compare 't' with 't', equal, continue
Compare ' ' with ' ', equal, continue
Find a digit. Consume all digits and build a number, compare the numbers, they are equal, so continue
Set the next character to evaluate to one after the number
Compare ' ' with ' ', equal, continue
Compare 'g' with 'b', equal, continue. 'g' -'b' is positive, so “cat 10 gray” is greater than “cat 10 black”. The result is available. No need to continue. Stop the function and return the result.
Now, an example with 2 different numbers. Example: “cat 2 gray” and “cat 10 gray”:
Compare 'C' with 'C', equal, continue
Compare 'a' with 'a', equal, continue
Compare 't' with 't', equal, continue
Compare ' ' with ' ', equal, continue
Find a digit. Consume all the digits and build a number, compare the numbers, one is 2 and the other is 10. Subtract 2-10. The result is negative. So, 2 is smaller than 10, and, with that, “cat 2 gray” is smaller than “cat 10 gray”.
If you make a “normal” comparison, then the result is opposite.
Let us come to the implementation. It is not that complicated.
// Needed for the comparison function
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
// Needed for the test code and output
#include <vector>
#include <utility>
#include <iomanip>
// Natural sort function. Limited to signed char strings
int naturalSort(const std::string& s1, const std::string& s2) {
// We want to iterate over both strings
const char* i1 = s1.data(); // Get a pointer to the beginning of string 1
const char* i2 = s2.data(); // Get a pointer to the beginning of string 2
// Result of comparison. 0 means equal, positive means s1>s2, negative means s1<s2
int result = 0;
// As long as both characters/numbers are equal and there are still characters in the string
do {
// If we found a digit at the same position in both strings
if (std::isdigit(*i1) and std::isdigit(*i2)) {
std::size_t pos1{}, pos2{}; // This will later indicate how many digits we read
// Convert the strings to numbers and compare them
result = std::stoi(i1, &pos1) - std::stoi(i2, &pos2);
// Set pointers to the position after the number
i1 += pos1; i2 += pos2;
}
else {
// Normal character
result = (*i1 - *i2);
++i1; ++i2;
}
} while ((result == 0) and (*i1 != 0 or *i2 != 0));
// Let's limit the output to -1, 0 ,1
return std::clamp(result, -1, 1);
}
// Driver / test code
int main() {
std::vector<std::pair<std::string, std::string>> test{
{"",""},
{"ABC",""},
{"","ABC"},
{"ABC","ABD"},
{"ABC","ABC"},
{"ABD","ABC"},
{"ABC","ABCD"},
{"ABCD","ABC"},
{"ABC","ABCD "},
{"ABCD","ABC "},
{"1",""},
{"","1"},
{"1","10"},
{"10","1"},
{" 1","1"},
{"1"," 1"},
{"a1","aa1"},
{"aa1","a1"},
{"A10B","A10C"},
{"A10B","A11B"},
{"A11B","A10B"},
{"A1BC","A10BC"},
{"A10BC","A1BC"},
{"CAT 1","CAT 10"},
{"CAT 10","CAT 1"},
{"CAT1","CAT10"},
{"CAT10","CAT1"},
{"CAT10","CAT10"},
{"AXYZ1BC","AXYZ10BC"},
{"AXYZ10BC","AXYZ1BC"},
{"AXYZ1000BCDEF","AXYZ1001BCDEF"},
{"AXYZ1001BCDEF","AXYZ1000BCDEF"},
{"AXYZ1000BCDEFGH","AXYZ1001BCDEF"},
{"AXYZ1001BCDEFGH","AXYZ1000BCDEF"},
};
for (const auto& [s1, s2] : test)
std::cout << std::right << std::setw(15) << s1 << " <comp> " << std::left << std::setw(15) << s2 << " -> " << naturalSort(s1, s2) << '\n';
}
OK, I hope that this is understandable.
Let us build a functor for that and use it with std::sort for sorting a std::vector "naturally".
// Needed for the comparison function
#include <iostream>
#include <string>
#include <cctype>
#include <algorithm>
// Needed for the test code and output
#include <vector>
#include <utility>
#include <iomanip>
// FUNCTOR for Natural sort function. Limited to signed char strings
struct NaturalSort {
bool operator ()(const std::string& s1, const std::string& s2) {
// We want to iterate over both strings
const char* i1 = s1.data(); // Get a pointer to the beginning of string 1
const char* i2 = s2.data(); // Get a pointer to the beginning of string 2
// Result of comparison. 0 means equal, positive means s1>s2, negative means s1<s2
int result = 0;
// As long as both characters/numbers are equal and there are still characters in the string
do {
// If we found a digit at the same position in both strings
if (std::isdigit(*i1) and std::isdigit(*i2)) {
std::size_t pos1{}, pos2{}; // This will later indicate how many digits we read
// Convert the strings to numbers and compare them
result = std::stoi(i1, &pos1) - std::stoi(i2, &pos2);
// Set pointers to the position after the number
i1 += pos1; i2 += pos2;
}
else {
// Normal character
result = (*i1 - *i2);
++i1; ++i2;
}
} while ((result == 0) and (*i1 != 0 or *i2 != 0));
// Let's limit the output to -1, 0 ,1
return result < 0;
}
};
// Driver / test code
int main() {
std::vector<std::string> test{ "Cat 1", "Cat 2", "Cat 10", "Cat 20", "Cat" };
std::cout << "\nNormal sort:\n\n";
std::sort(test.begin(), test.end());
for (const std::string& s : test) std::cout << s << '\n';
std::cout << "\n\nNatural sort:\n\n";
std::sort(test.begin(), test.end(), NaturalSort());
for (const std::string& s: test) std::cout << s << '\n';
}
Program output:

How to get truth table of function (( c + ~d ) * b ) * ~( d + a * e )

SO I have the equation (( c + ~d ) * b ) * ~( d + a * e ) of which I'm trying to generate a truth table but I'm unsure how I would even start with getting the program to compute whether or not the the variable should be equal to true or false according to the truth table. Any suggestions as how to do this? Thank you in advance.
#include<iostream>
using namespace std;
bool checkBoolTF(int a){
bool TF;
if(a == 0){
TF = false;
}
else{
TF = true;
}
return TF;
}
int main()
{
int a,b,c,d,e;
bool aBool, bBool, cBool, dBool, eBool;
string equation = "(( c + ~d ) * b ) * ~( d + a * e )";
bool equationTF;
//LOOP TO TRUTH TABLE - FINAL VALUES
cout << "----------------------------------------------------------------------" << endl;
cout << "| a | b | c | d | e | " << equation << " |" << endl;
cout << "----------------------------------------------------------------------" << endl;
for(a=0;a<=1;a++){
checkBoolTF(a);
for(b=0;b<=1;b++){
checkBoolTF(b);
for(c=0;c<=1;c++){
checkBoolTF(c);
for(d=0;d<=1;d++){
checkBoolTF(d);
for(e=0;e<=1;e++){
checkBoolTF(e);
cout << "| " << a << " | " << b << " | " << c << " | " << d << " | " << e << " | " << equationTF << " |" << endl;
cout << "----------------------------------------------------------------------" << endl;
}
}
}
}
}
return 0;
}
Step 1: Tokenize.
enum class TokenType {
bracket, binop, binaryop, var, literal
};
struct Token {
TokenType type;
char value;
};
convert the string to a vector of token.
You aren't using literal yet: it is the values 0 or 1. You'll use it later.
Write code that pretty prints a vector of tokens.
Step 2: make a simple tree.
struct Tree {
bool is_token=true;
Token token;
std::vector<Tree> tree;
};
change your first code to generate a tree, containing a vector of tokens.
Write code that pretty prints it. Test.
Step 3: Reduce the tree
Step 3a: Brackets
Now do a reduction step; walks a vector of trees and generates one. It copies everuthing that isn't a bracket blindly to the output. If it sees a ( it copies everything until the matching ) (count open and closed) into a sub-tree, then copies that sub-tree into the output.
It takes "a ( b c )" and makes it a then b c in a subtree.
Write code that can pretty print subtrees. Test.
Step 3b: nested brackets
Next, recurse on the subtree you make, so its nested brackets also get put into subtrees.
Step 3c: operators
Next, work on operators. ~ is easy: it swallows the next tree in the vector. As + binds loser than *, for each + make two subtrees; one for everything before, one for everything after. Then do a pass dping the same for *.
After all this, you turn
a+(b+c)*~(d+e)
into
+ (a , ( * (+ (b, c), ~(+(d,e))))
Step 4: substitute
Map a std::map that maps the variable to a value. Take a copy of a tree, and walk it replacing each variable with a literal equal to its value.
Step 5: evaluate
For each operator, evaluate the subtree(s) then apply the operator.
The result should be a 0 or a 1.
4 and 5 can be done independently by starting with a literal expression.
So I have a personal program that implements this for a strings with a form
"Ab|c(d|E)|fa"
my full source code is a complete mess and contains serveral other things I'm trying to do at the same time (failling to simplify the expression by circling kmaps and stuff)
However I can walk through what I've done if it helps
its setup to be easier for me to parse with capitals representing positive and lower case letters representing negation/not () representing sub expressions and [] representing negated sub expressions
so the input string `"ABC(DEF)G(HI(KK)S[as][ge])S" is converted into this .repr() structure
AND(
A
B
C
AND( D E F )
G
AND(
H
I
AND( K K )
S
NAND( !A !S )
NAND( !G !E )
)
S
)
and something like "Ab|cb" is
OR(
AND( A !B )
AND( !C !B )
)
I have a object (I call expression) that contains information about its type stored in something like the following
namespace xpr { //expression types
enum typ {
identity_,
negation_,
and_,
or_,
nand_,
nor_
};
}
class expression{
...
xpr::typ type = xpr::identity_;
char value = ' ';
std::vector<expression> sub_expressions;
...
};
and either a char that is its value or a vector of expressions. (and or nor nand expressions)
Parsing it into this expression form is done through nested constructors that keep passing the current position in the string as well as its level.
finally to answer your question
std::vector<char> vars = trackUsed();
// equivalent to a set but more efficent to do the sort/unique at the end one time.
removeDuplicates(vars);
const auto truth_table_width = vars.size();
const auto truth_table_size = (size_t)std::pow((size_t)2, truth_table_width); // 2^width
expression::test_type test; // abc through !a!b!c
test.reserve(truth_table_width);
for ( const auto &v : vars ) {
// value_type is value: 6, sign: 2 so character has to fit in 6bits and sign in 2.
// minus 'A' to make A-Z 0-26
test.emplace_back(v - 'A', xpr::negative);
}
for ( size_t i = 0; i < truth_table_size; i++ ) {
for ( size_t j = 0; j < truth_table_width; j++ ) {
// converts 0 to negative and 1 to positive
test[j].sign = (xpr::sign_type)((i >> j) & 0x1);
}
bool valid = testValues(test);
if ( valid ) {
sum_of_products.push_back(test);
}
}
I set up a truth table by extracting all the characters used removing duplicates and sorting them. making a vector<vector< implmentation defined object >>
incrementing a value to the max truth table width and using the sign bit of that value to populate the truth table - 0 = [0, 0, ... 1 = [1, 0, ... 2 = [0, 1, ... etc
and then looping through the outer vector and sending the inner vector to a "testValues" member function that is specialized for each expression type
// given A true B true C true see if whole expression evaluates to true.
bool expression::testValues(const potion::test_type& values) const {
if ( this->is_simple() ) {
auto val = std::lower_bound(values.begin(), values.end(),
this->value,
[ ](potion::val_type lhs, char rhs) -> bool {return lhs < rhs; }
);
if ( type == xpr::identity_ ) return (*val).sign;
if ( type == xpr::negation_ ) return !(*val).sign;
}
if ( type == xpr::and_ || type == xpr::nand_ ) {
const bool is_and = type == xpr::and_; //used to combine and and nand expressions and return the oposite val for nand
for ( const auto& e : sub_expressions ) {
if ( e.testValues(values) == false ) return !is_and; // short circuit- if b is false then abc is false
}
return is_and;
}
if ( type == xpr::or_ || type == xpr::nor_ ) {
const bool is_or = type == xpr::or_; //used to combine or and nor and return the oposite val for nor
for ( const auto& e : sub_expressions ) {
if ( e.testValues(values) == true ) return is_or; // short circuit- if b is true then a|b|c is true
}
return !is_or;
}
throw std::runtime_error("Expression can't be simplified. Type not valid"); //should never happen
return false;
}
There's obviously tons and tons of boilerplate code/ parsing code that's probably not the best. And if you want to parse strings using the "custom language" you are defining "(( c + ~d ) * b ) * ~( d + a * e )"
then the parsing code will obviously be a lot different.
Anyway I hope this is helpful for your project. TLDR: might be a bit harder to implement than you initially thought. Although everything I've done is functional the code isn't the cleanest and its heavly setup for my specific case- only obtaining the truth table entries that have are positive and storing them in a sum of product that can be processed further.
For a start, you can simplify the checkBoolTF function to something like:
bool checkBoolTF (int a)
{
return !(a==0);
}
Secondly, it seems like in the for loops, the values returned by this function are not being assigned to anything and are therefore lost. So you probably want to define an aux variable:
bool auxA = checkBoolTF(a);
and so on..
I would like to show an additional, already existing solution. It is well structured and commented. It is published at github. Please see here
The intended purpose of this program is to calculate MCDC test pairs. But it does of course also all that you want. I do not recommend to copy and paste, but you could read and learn, how to do your implementation.
This code reads exactly the strings that you specified. It also creates a truth table. But this is only a minor part of the whole functionality.
So, what you need to do, is, to compile the string in something that could can be evaluated as a boolean expression.
For that, I first defined the input alphabet and the language, described by a grammar. Then, I created a compiler, consisting of a scanner (lexer), parser and code generator. Actually I created 2 compilers, with the same front end and 2 different back ends. So, 2 different code generators. One, for a virtual machine that can evaluate the boolean expression for any combination of input variables. And, the 2nd backend, will create an abstract syntax tree, with which I evaluate all possible MCDC test pairs.
As said, the first code generator creates Op code for a virtual machine. With this machine, the truth table and with that all minterms are calculated. Then Quine and McCluskey is used (2 different implementations) to minimize the boolean expression. And at the end, and optimzed version of Petricks method is used to solve the unate coverage problem and identify the minimum set of prime implicants.
The MCDC part is maybe a little bit too complex to explain here.
But the main message is, that you first need to parse your string and convert it in something executable.
Then you can evaluate whatever you want.

Permutation on a strange string

There is a strange string of 10 characters ether '0' or '1'. I have n filter strings each having 10 characters ether '0' or '1'. A '1' at the i-th position in a filter string means that if I applies this filter to the i-th character of the strange string, i-th character of strange string will be inverted: it becomes '1' if it was '0', and vice versa, whereas a '0' at the i-th position in a filter string will not do anything to the strange string. I can apply any number of filters. I can pick any number of filters and can apply to strange string. Now i want to find how many different subsets of all the filters can I apply to transform this strange string so that strange string will contain only 1's? I am not able to generalise the problem for any number of strings. Can anybody help.
Let us have some test cases
Enter strange string :1111111111
Total filter strings : 2
Enter filter strings :
0000000000
0000000000
Output is: 4
Explanation : Strange string is already having all characters 1's, and I have two different identity filters. I can either apply the empty subset of filters, the first filter only, the second filter only, or both.
Enter strange string :0101010101
Total filter strings : 3
Enter filter strings :
1010101010
1010000000
0000101010
Output is: 2
Explanation : I can either apply the first filter (and invert all 0's) or apply the second and third filters in any order.
Brute force algorithm:
std::uint16_t apply_filters(std::uint16_t init,
const std::vector<std::uint16_t>& filters,
const std::vector<bool>& mask)
{
auto res = init;
for (std::size_t i = 0; i != filters.size(); ++i) {
if (mask[i]) {
res ^= filters[i];
}
}
return res;
}
bool increase(std::vector<bool>& bs)
{
for (std::size_t i = 0; i != bs.size(); ++i) {
bs[i] = !bs[i];
if (bs[i] == true) {
return true;
}
}
return false; // overflow
}
std::size_t count_filters_combination(std::uint16_t init,
const std::vector<std::uint16_t>& filters)
{
std::vector<bool> bs(filters.size());
std::size_t count = 0;
const std::uint16_t expected = 0b1111111111;
do
{
if (expected == apply_filters(init, filters, bs)) {
++count;
}
} while (increase(bs));
return count;
}
Live Demo
I wrote my solution in python. It should be pretty easy to understand. I'll leave it to you to translate it to C++.
def filterCombinations(original, filters):
combinations = 1 if original == 0b1111111111 else 0
for i in xrange(len(filters)):
newvalue = original ^ filters[i]
newfilters = filters[i+1:]
combinations += filterCombinations(newvalue, newfilters)
return combinations
Using 3 filters, the first level of recursion looks like this:
filterCombinations(S, [F1, F2, F3])
--> X +
filterCombinations(S^F1, [F2, F3]) +
filterCombinations(S^F2, [F3]) +
filterCombinations(S^F3, [])
Where X is 1 if S == 1111111111 and 0 otherwise.

Given a word and a text, return the count of the occurrences of anagrams of the word in the text [duplicate]

This question already has answers here:
Given a word and a text, we need to return the occurrences of anagrams
(6 answers)
Closed 9 years ago.
For eg. word is for and the text is forxxorfxdofr, anagrams of for will be ofr, orf, fro, etc. So the answer would be 3 for this particular example.
Here is what I came up with.
#include<iostream>
#include<cstring>
using namespace std;
int countAnagram (char *pattern, char *text)
{
int patternLength = strlen(pattern);
int textLength = strlen(text);
int dp1[256] = {0}, dp2[256] = {0}, i, j;
for (i = 0; i < patternLength; i++)
{
dp1[pattern[i]]++;
dp2[text[i]]++;
}
int found = 0, temp = 0;
for (i = 0; i < 256; i++)
{
if (dp1[i]!=dp2[i])
{
temp = 1;
break;
}
}
if (temp == 0)
found++;
for (i = 0; i < textLength - patternLength; i++)
{
temp = 0;
dp2[text[i]]--;
dp2[text[i+patternLength]]++;
for (j = 0; j < 256; j++)
{
if (dp1[j]!=dp2[j])
{
temp = 1;
break;
}
}
if (temp == 0)
found++;
}
return found;
}
int main()
{
char pattern[] = "for";
char text[] = "ofrghofrof";
cout << countAnagram(pattern, text);
}
Does there exist a faster algorithm for the said problem?
Most of the time will be spent searching, so to make the algorithm more time efficient, the objective is to reduce the quantities of searches or optimize the search.
Method 1: A table of search starting positions.
Create a vector of lists, one vector slot for each letter of the alphabet. This can be space-optimized later.
Each slot will contain a list of indices into the text.
Example text: forxxorfxdofr
Slot List
'f' 0 --> 7 --> 11
'o' 1 --> 5 --> 10
'r' 2 --> 6 --> 12
For each word, look up the letter in the vector to get a list of indexes into the text. For each index in the list, compare the text string position from the list item to the word.
So with the above table and the word "ofr", the first compare occurs at index 1, second compare at index 5 and last compare at index 10.
You could eliminate near-end of text indices where (index + word length > text length).
You can use the commutativity of multiplication, along with uniqueness of primal decomposition. This relies on my previous answer here
Create a mapping from each character into a list of prime numbers (as small as possible). For e.g. a-->2, b-->3, c-->5, etc.. This can be kept in a simple array.
Now, convert the given word into the multiplication of the primes matching each of its characters. This results will be equal to a similar multiplication of any anagram of that word.
Now sweep over the array, and at any given step, maintain the multiplication of the primes matching the last L characters (where L is the length of your word). So every time you advance you do
mul = mul * char2prime(text[i]) / char2prime(text[i-L])
Whenever this multiplication equals that of your word - increment the overall counter, and you're done
Note that this method would work well on short words, but the primes multiplication can overflow a 64b var pretty fast (by ~9-10 letters), so you'll have to use a large number math library to support longer words.
This algorithm is reasonably efficient if the pattern to be anagrammed is so short that the best way to search it is to simply scan it. To allow longer patterns, the scans represented here by the 'for jj' and 'for mm' loops could be replaced by more sophisticated search techniques.
// sLine -- string to be searched
// sWord -- pattern to be anagrammed
// (in this pseudo-language, the index of the first character in a string is 0)
// iAnagrams -- count of anagrams found
iLineLim = length(sLine)-1
iWordLim = length(sWord)-1
// we need a 'deleted' marker char that will never appear in the input strings
chNil = chr(0)
iAnagrams = 0 // well we haven't found any yet have we
// examine every posn in sLine where an anagram could possibly start
for ii from 0 to iLineLim-iWordLim do {
chK = sLine[ii]
// does the char at this position in sLine also appear in sWord
for jj from 0 to iWordLim do {
if sWord[jj]=chK then {
// yes -- we have a candidate starting posn in sLine
// is there an anagram of sWord at this position in sLine
sCopy = sWord // make a temp copy that we will delete one char at a time
sCopy[jj] = chNil // delete the char we already found in sLine
// the rest of the anagram would have to be in the next iWordLim positions
for kk from ii+1 to ii+iWordLim do {
chK = sLine[kk]
cc = false
for mm from 0 to iWordLim do { // look for anagram char
if sCopy[mm]=chK then { // found one
cc = true
sCopy[mm] = chNil // delete it from copy
break // out of 'for mm'
}
}
if not cc then break // out of 'for kk' -- no anagram char here
}
if cc then { iAnagrams = iAnagrams+1 }
break // out of 'for jj'
}
}
}
-Al.

How to get the shortest palindrome of a string

For example :
String is : abcd
shortest palindrome is abcdcba is the solution
longer palindrome can be : abcddcba
another example:
String : aaaab
shortest palindrome is aaaabaaaa
longer palindrome can be aaaaabbaaaa
Restrictions : you can only add characters in the end.
Just append the reverse of initial substrings of the string, from shortest to longest, to the string until you have a palindrome. e.g., for "acbab", try appending "a" which yields "acbaba", which is not a palindrome, then try appending "ac" reversed, yielding "acbabca" which is a palindrome.
Update: Note that you don't have to actually do the append. You know that the substring matches since you just reversed it. So all you have to do is check whether the remainder of the string is a palindrome, and if so append the reverse of the substring. Which is what Ptival wrote symbolically, so he should probably get the credit for the answer. Example: for "acbab", find the longest suffix that is a palindrome; that is "bab". Then append the remainder, "ac", in reverse: ac bab ca.
My guess for the logic:
Say you string is [a1...an] (list of characters a1 to an)
Find the smallest i such that [ai...an] is a palindrome.
The smallest palindrome is [a1 ... a(i-1)] ++ [ai ... an] ++ [a(i-1) ... a1]
where ++ denotes string concatenation.
Some pseudo code, to leave at least a bit of work on you:
def shortPalindrome(s):
for i in range(len(s)):
pal = s + reverse(s[0:i])
if isPalindrome(pal):
return pal
error()
Python code, should be easy to convert to C:
for i in range(1, len(a)):
if a[i:] == a[i:][::-1]:
break
print a + a[0:i][::-1]
I was also asked the same question recently, and here is what I wrote for my interview:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int isPalin ( char *str ) {
int i, len=strlen(str);
for (i=0; i<len/2; ++i)
if (str[i]!=str[len-i-1])
break;
return i==len/2;
}
int main(int argc, char *argv[]) {
if (argc!=2)
puts("Usage: small_palin <string>");
else {
char *str = argv[1];
int i=0, j, len=strlen(str);
while ( !isPalin(str+i) )
++i;
char *palin = malloc(len+1+i);
*(palin+len+1+i) = '\0';
strcpy(palin,str);
for (i=i-1, j=0; i>=0; --i, ++j)
*(palin+len+j) = str[i];
puts(palin);
}
return 0;
}
I feel that the program would have been more structured had I written an strrev() function and checked palindrome using strcmp(). This would enable me to reverse the starting characters of the source string and directly copy it using strcpy().
The reson why I went with this solution is that before this question I was asked to check for palindrome and I already had that isPalin() in paper. Kind of felt using existing code would be better !!
From the examples you shown looks like the longest palindrome is the original string concatenated with its reverse, and the shortest is the original string concatenated with its reverse except for the first character. But I'm pretty sure you want something more complex. Perhaps you can give better examples?
if string is made of k chars, I think you should add to this string the reversed (k-1) chars...
Below is my answer for another case: shortest palindrome by attaching characters to the front. So your task is to understand the algorithm and modify it appropriately.
Basically, it states that from a string s find the shortest palindrome by adding some characters to the front of s.
If you have never tried to solve this problem, I suggest that you solve it, and it will help you improve your problem solving skill.
After solving it, I kept looking for better solutions. I stumbled upon another programmer's solution. It is in python, and really neat. It is really interesting, but later I found out it was wrong.
class Solution:
# #param {string} s
# #return {string}
def shortestPalindrome(self, s):
A=s+s[::-1]
cont=[0]
for i in range(1,len(A)):
index=cont[i-1]
while(index>0 and A[index]!=A[i]):
index=cont[index-1]
cont.append(index+(1 if A[index]==A[i] else 0))
print cont[-1]
return s[cont[-1]:][::-1]+s
I myself looked at the Solution and saw it's interesting idea. At first, the algorithm concatenates the string and its reversed version. Then the following steps are similar to the steps for building KMP-table (or failure function) using in KMP algorithm. Why does this procedure work?
If you know KMP text searching algorithm, you will know its "lookup table" and steps to build it. Right now, I just show one important use of the table: it can show you the longest prefix of a string s that is also suffix of s (but not s itself). For example, "abcdabc" has the longest prefix which is also a suffix: "abc" (not "abcdabc" since this is the entire string!!!). To make it fun, we call this prefix is "happy substring" of s. So the happy substring of "aaaaaaaaaa" (10 a's ) is "aaaaaaaaa" (9 a's).
Now we go back and see how finding happy sub string of s can help solve the shortest palindrome problem.
Suppose that q is the shortest string added to the front of s to make the string qs is a palindrome. We can see that obviously length(q) < length(s) since ss is also a palindrome. Since qs is a palindrome, qs must end with q, or s = p+q where p is a sub string of s. Easily we see that p is also a palindrome. Therefore, in order to have shortest qs, q needs to be shortest. In turn, p is the longest palindromic sub string of s.
We call s' and q' are the reversed strings of s and q respectively. We see that s = pq, s' = q'p since p is a palindrome. So ss' = pqq'p . Now we need to find the longest p. Eureka! This also means that p is a happy sub string of the string ss'. That's how the above algorithm works!!!
However, after some thought, the above algorithm has some loophole. p is not a happy sub string of ss'! In fact, p is the longest prefix that is also a suffix of ss', but the prefix and suffix must not overlap each other. So let's make it more fun, we call "extremely happy sub string" of a string s is the longest sub string of s that is a prefix and also a suffix and this prefix and suffix must not overlap. On the other word, the "extremely happy sub string" of s must have length less than or equal half length of s.
So it turns out the "happy sub string" of ss' is not always "extremely happy sub string" of ss'. We can easily construct an example: s = "aabba". ss'="aabbaabbaa". The happy sub string of "aabbaabbaa" is "aabbaa", while the extremely happy sub string of "aabbaabbaa" is "aa". Bang!
Hence, the correct solution should be as following, based on the observation that length(p) <= length(ss')/2.
class Solution:
# #param {string} s
# #return {string}
def shortestPalindrome(self, s):
A=s+s[::-1]
cont=[0]
for i in range(1,len(A)):
index=cont[i-1]
while(index>0):
if(A[index]==A[i]):
if index < len(s):
break
index=cont[index-1]
cont.append(index+(1 if A[index]==A[i] else 0))
print cont[-1]
return s[cont[-1]:][::-1]+s
Hooray!
As you can see, algorithms are interesting!
The link to the article I wrote here
It looks like the solutions outlined here are O(N^2) (for each suffix X of the reversed string S, find if S + X is a palindrome).
I believe there is a linear, i.e O(N) solution for this problem. Consider the following statement: the only time where you would append less characters than S.Length - 1 is when the string already contains a partial palindrome, so it will be in the form of NNNNNPPPPPP, where PPPPP represent a palindrome. This means that if we can find the largest trailing palindrome, we can solve it linearly by concatenating the reverse of NNNNN to the end.
Finally, there exists a famous algorithm (Manacher, 1975) that finds the longest (and in fact, all) of the palindromes contained in a string (there is a good explanation here). It can be easily modified to return the longest trailing palidrome, thus giving a linear solution for this problem.
If anyone is interested, here is the full code for a mirror problem (append characters at the beginning):
using System.Text;
// Via http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
class Manacher
{
// Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
private static string PreProcess(string s)
{
StringBuilder builder = new StringBuilder();
int n = s.Length;
if (n == 0) return "^$";
builder.Append('^');
for (int i = 0; i < n; i++)
{
builder.Append('#');
builder.Append(s[i]);
}
builder.Append('#');
builder.Append('$');
return builder.ToString();
}
// Modified to return only the longest palindrome that *starts* the string
public static string LongestPalindrome(string s)
{
string T = PreProcess(s);
int n = T.Length;
int[] P = new int[n];
int C = 0, R = 0;
for (int i = 1; i < n - 1; i++)
{
int i_mirror = 2 * C - i; // equals to i' = C - (i-C)
P[i] = (R > i) ? Math.Min(R - i, P[i_mirror]) : 0;
// Attempt to expand palindrome centered at i
while (T[i + 1 + P[i]] == T[i - 1 - P[i]])
P[i]++;
// If palindrome centered at i expand past R,
// adjust center based on expanded palindrome.
if (i + P[i] > R)
{
C = i;
R = i + P[i];
}
}
// Find the maximum element in P.
int maxLen = 0;
int centerIndex = 0;
for (int i = 1; i < n - 1; i++)
{
if (P[i] > maxLen
&& i - 1 == P[i] /* the && part forces to only consider palindromes that start at the beginning*/)
{
maxLen = P[i];
centerIndex = i;
}
}
return s.Substring((centerIndex - 1 - maxLen) / 2, maxLen);
}
}
public class Solution {
public string Reverse(string s)
{
StringBuilder result = new StringBuilder();
for (int i = s.Length - 1; i >= 0; i--)
{
result.Append(s[i]);
}
return result.ToString();
}
public string ShortestPalindrome(string s)
{
string palindrome = Manacher.LongestPalindrome(s);
string part = s.Substring(palindrome.Length);
return Reverse(part) + palindrome + part;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
public class Test
{
public static void shortPalindrome(string [] words){
List<string> container = new List<string>(); //List of Palindromes
foreach (string word in words )
{
char[] chararray = word.ToCharArray();
Array.Reverse(chararray);
string newText = new string(chararray);
if (word == newText) container.Add(word);
}
string shortPal=container.ElementAt(0);
for(int i=0; i<container.Count; i++)
{
if(container[i].Length < shortPal.Length){
shortPal = container[i];
}
}
Console.WriteLine(" The Shortest Palindrome is {0}",shortPal);
}
public static void Main()
{
string[] word = new string[5] {"noon", "racecar","redivider", "sun", "loss"};
shortPalindrome(word);
}
}
Shortest palindrome -
Reverse iterate from last positon + 1 to beginning
Push_back the elements
#include <iostream>
#include <string>
using namespace std ;
int main()
{
string str = "abcd" ;
string shortStr = str ;
for( string::reverse_iterator it = str.rbegin()+1; it != str.rend() ; ++it )
{
shortStr.push_back(*it) ;
}
cout << shortStr << "\n" ;
}
And longer palindrome can be any longer.
Ex: abcd
Longer Palindrome - abcddcba, abcdddcba, ...