i want to pick the integer combinations using a single integer,
like I have a number 1234.. Now what i want is: 1,2,3,4,12,23,34,123,234,1234
Kindly help..??
If I understood you right, you want all substrings of a given string (in this case the number 1234). So, for a string of length n there are n substrings of length 1, n − 1 substrings of length 2, etc. until one substring of length n.
Given that you can easily solve this with two nested loops, e.g.:
public static IEnumerable<int> Foo(int x) {
string s = x.ToString();
for (int length = 1; length <= s.Length; length++) {
for (int i = 0; i + length < s.Length; i++) {
yield return int.Parse(s.Substring(i, length));
}
}
}
(Untested and there are likely fencepost errors, but you get the idea.)
How about this article on Permutations, Combinations, and Variations using C# Generics
where permutations and combination are discussed, with code.
Related
Problem statement:
Using just the ElementAt, Length, and Substring string methods and the + (concatenate)
operator, write a function that accepts a string s, a start position p, and a length l, and returns s with the characters starting in position p for a length of l removed. Don’t forget that strings start at position 0. Thus (“abcdefghijk”, 2, 4) returns “abghijk”. Don’t use any “remove” or similar built-in string gadget.
I tried to do this
static string rstring(string str, int p, int l)
{
string end= "";
for (int i=0 ; i<p; i++){
end+= str[i];
}
for (int i=p+l ; i<str.length i++){
end+= str[i];
}
return end;
}
I tried to do this but i couldn't figure out to use ElementAT and substring. Any help will be appricated.
You're using [] which is essentially the same thing as ElementAt, and if you look at your loops they're basically doing the same thing as Substring, albeit less efficiently because you're building up and throwing away a bunch of intermediate strings.
That said, I don't see why you'd use both -- you'd just use one or the other.
If you don't want to use Substring() or Remove() or any other string maninpulation I would use a simple loop (this doesn't include, but should include error handling).
for (int i=0; i < str.Length; i++)
{
if (i < p || i > l+1) end += str[i];
}
This basically just accepts a string, a start and an end and then returns a new string according to those parameters.
This is probably the easiest way to explain Substrings. They accept a start and end and then give you back a new string according to your start and end.
public string ReturnSubstring(string str, int start, int end)
{
return str.Substring(start, end);
}
var firstHalf = ReturnSubstring(myString, 0, 3);
var secondHalf = ReturnSubstring(myString, 6, myString.Length);
var newString = firstHalf + secondHalf;
I am trying to write a code that sums the digits of a number and it should work, but I can't find where I am doing it wrong, I have a working code in Python for this and I tried to do it the same way in C# but.. Here are the two codes
Python:
number = "12346546"
summ=0
for i in number:
summ+=int(i)
print summ
C#:
string num = "2342";
int sum = 0;
for (int i = 0; i < num.Length; i++)
{
int number = Convert.ToInt32(num[i]);
sum += number;
}
Console.WriteLine(sum);
Edit: I used the Debugger and I found that when I am converting the numbers they turn out to be completely different numbers, but if I convert the whole string then it is converting correctly... how to fix this?
num[i] is a char and Convert.ToInt32 will return the ASCII code of the char instead of the actual numerical value.Use:
int number = Convert.ToInt32(num[i].ToString());
Also change i < num.Length-1 to i < num.Length
Edit: To make it more clear here is an example:
int n1 = Convert.ToInt32('0'); // Uses Convert.ToInt32(char) result -> 48
int n2 = (int) '0'; // cast from char to int result -> 48
int n3 = Convert.ToInt32("0"); // Uses Convert.ToInt32(string) result -> 0
replace Convert.ToInt32(num[i])
by
Convert.ToInt32(num[i].ToString())
else, you will get an ascii value... (cause num[i] is a char)
see msdn
There is no null at the end of a C# string, so you don't have to worry about it, and thus do not require the "-1" in your loop. However, there is a much easier way:
string num = "2342";
int sum = num.ToCharArray().Select(i => int.Parse(i.ToString())).Sum();
This converts the string to a character array, converts them all to ints (returning an IEnumerable<int> in the process) and then returns the sum of them all.
Convert.ToInt32(num[i]); would give you the ASCII value for the character digit. For example for character 1 you will get 49.
Use char.GetNumericValue like:
for (int i = 0; i < num.Length; i++)
{
int number = (int) char.GetNumericValue((num[i]));
sum += number;
}
You also need to modify your loop to continue till Length, since you are using <.
If you want to use LINQ then you can do:
int sum = num.Select(r => (int)char.GetNumericValue(r)).Sum();
A one line solution using Linq:
string num = "2342";
int sum = num.Sum(c=> Convert.ToInt32(c.ToString()));
Here's a fiddle: https://dotnetfiddle.net/3jt7G6
You can combine a few things.
You can select a collection of chars from a string using Linq (Sum() is a Linq method).
You still need to convert those characters into numbers; you can do this by converting a character to a string and parsing that or you can use another built-in method.
var sum = num.Sum(i => Char.GetNumericValue(i));
char is, at its core, just a number. It just happens to be a number representing a character.
Here are some solutions that highlight this:
int sum = num.Sum(c => c) - '0' * num.Length;
// or
int sum = 0;
for (int i = 0; i < num.Length; i++)
{
sum += num[i] - '0';
}
I'm trying to calculate
If we calculated every possible combination of numbers from 0 to (c-1)
with a length of x
what set would occur at point i
For example:
c = 4
x = 4
i = 3
Would yield:
[0000]
[0001]
[0002]
[0003] <- i
[0010]
....
[3333]
This is very nearly the same problem as in the related question Logic to select a specific set from Cartesian set. However, because x and i are large enough to require the use of BigInteger objects, the code has to be changed to return a List, and take an int, instead of a string array:
int PossibleNumbers;
public List<int> Get(BigInteger Address)
{
List<int> values = new List<int>();
BigInteger sizes = new BigInteger(1);
for (int j = 0; j < PixelArrayLength; j++)
{
BigInteger index = BigInteger.Divide(Address, sizes);
index = (index % PossibleNumbers);
values.Add((int)index);
sizes *= PossibleNumbers;
}
return values;
}
This seems to behave as I'd expect, however, when I start using values like this:
c = 66000
x = 950000
i = (66000^950000)/2
So here, I'm looking for the ith value in the cartesian set of 0 to (c-1) of length 950000, or put another way, the halfway point.
At this point, I just get a list of zeroes returned. How can I solve this problem?
Notes: It's quite a specific problem, and I apologise for the wall-of-text, I do hope it's not too much, I was just hoping to properly explain what I meant. Thanks to you all!
Edit: Here are some more examples: http://pastebin.com/zmSDQEGC
Here is a generic base converter... it takes a decimal for the base10 value to convert into your newBase and returns an array of int's. If you need a BigInteger this method works perfectly well with just changing the base10Value to BigInteger.
EDIT: Converted method to BigInteger since that's what you need.
EDIT 2: Thanks phoog for pointing out BigInteger is base2 so changing the method signature.
public static int[] ConvertToBase(BigInteger value, int newBase, int length)
{
var result = new Stack<int>();
while (value > 0)
{
result.Push((int)(value % newBase));
if (value < newBase)
value = 0;
else
value = value / newBase;
}
for (var i = result.Count; i < length; i++)
result.Push(0);
return result.ToArray();
}
usage...
int[] a = ConvertToBase(13, 4, 4) = [0,0,3,1]
int[] b = ConvertToBase(0, 4, 4) = [0,0,3,1]
int[] c = ConvertToBase(1234, 12, 4) = [0,8,6,10]
However the probelm you specifically state is a bit large to test it on. :)
Just calculating 66000 ^ 950000 / 2 is a good bit of work as Phoog mentioned. Unless of course you meant ^ to be the XOR operator. In which case it's quite fast.
EDIT: From the comments... The largest base10 number that can be represented given a particular newBase and length is...
var largestBase10 = BigInteger.Pow(newBase, length)-1;
The first expression of the problem boils down to "write 3 as a 4-digit base-4 number". So, if the problem is "write i as an x-digit base-c number", or, in this case, "write (66000^950000)/2 as a 950000-digit base 66000 number", then does that make it easier?
If you're specifically looking for the halfway point of the cartesian product, it's not so hard. If you assume that c is even, then the most significant digit is c / 2, and the rest of the digits are zero. If your return value is all zeros, then you may have an off-by-one error, or the like, since actually only one digit is incorrect.
I'm making a program in winforms application where in it generates random patterns with seven length of characters such as 2Vowels-5consonants, 3Vowels-4Consonants and so on..after which it generates random letters specific to the pattern generated..
After the letters are generated, I want to list all possible combinations of letters to that generated letters.. and try to check if the generated combinations are present on the system's dictionary..
-Sample Input-
Pattern : 3V-4C Letters: AIOLMNC
Combinations: AIO AOL OIL .... MAIL
.... CLAIM .... and so on...
-Output-
Words Found: OIL MAIL CLAIM ... and so on...
This program is intended for word games.. I'm asking for help and any suggestions that may help me to solve my problem. I can't think of proper way to start the algorithm and how to code it..
I don't normally do this, but I came up with an even better solution for your problem, and it deserves its own answer! This AnagramSolver solution is WAY more optimized than my other answer, because it doesn't create every-single-permutation of a word, and dictionary lookups are very optimized. Try it out:
Usage Example:
string[] dictionary = ReadDictionary(...);
var solver = new AnagramSolver(dictionary);
int minimumLength = 1;
IEnumerable<string> results = solver.SolveAnagram("AEMNS", minimumLength);
// Output the results:
foreach (var result in results)
{
Console.WriteLine(result);
}
// Output example:
// "NAMES", "MANES", "MEANS", "AMEN", "MANE", "MEAN", "NAME", "MAN", "MAE", "AM", "NA", "AN", "MA", "A",
Code:
public class AnagramSolver
{
public AnagramSolver(IEnumerable<string> dictionary)
{
// Create our lookup by keying on the sorted letters:
this.dictionary = dictionary.ToLookup<string, string>(SortLetters);
}
private ILookup<string, string> dictionary;
public IEnumerable<string> SolveAnagram(string anagram, int minimumLength)
{
return CreateCombinations(anagram, minimumLength)
// Sort the letters:
.Select<string, string>(SortLetters)
// Make sure we don't have duplicates:
.Distinct()
// Find all words that can be made from these letters:
.SelectMany(combo => dictionary[combo])
;
}
private static string SortLetters(string letters)
{
char[] chars = letters.ToCharArray();
Array.Sort(chars);
return new string(chars);
}
/// <summary> Creates all possible combinations of all lengths from the anagram. </summary>
private static IEnumerable<string> CreateCombinations(string anagram, int minimumLength)
{
var letters = anagram.ToCharArray();
// Create combinations of every length:
for (int length = letters.Length; length >= minimumLength; length--)
{
yield return new string(letters, 0, length);
// Swap characters to form every combination:
for (int a = 0; a < length; a++)
{
for (int b = length; b < letters.Length; b++)
{
// Swap a <> b if necessary:
char temp = letters[a];
if (temp != letters[b]) // reduces duplication
{
letters[a] = letters[b];
letters[b] = temp;
yield return new string(letters, 0, length);
}
}
}
}
}
}
Here's a summary of the algorithm:
The basic idea is that every set of anagrams derive from the same set of letters.
If we sort the letters, we can group together sets of anagrams.
I got this idea from Algorithm for grouping anagram words.
For example, a set of anagrams ("NAMES", "MANES", "MEANS") can be keyed on "AEMNS".
Therefore, once we create our dictionary lookup, it's incredibly easy and fast to solve the anagram -- simply sort the letters of the anagram and perform the lookup.
The next challenge is to find all "smaller" anagrams -- for example, finding "NAME", "SANE", "MAN", "AN", "A", etc.
This can be done by finding all combinations of the anagram.
Combinations are much easier to find than permutations. No recursion is needed. I implemented complete combinations with 3 loops and a simple swap! It took a while to get the algorithm right, but now that it's cleaned up, it's very pretty.
For each combination found, we must again sort the letters and perform the lookup.
This gives us all possible solutions to the anagram!
Update
This solution directly answers your question ("How do I form all combinations of characters"), but this is not a very efficient way to solve anagrams. I decided to create a better solution for solving anagrams, so please see my other answer.
This sounds like a fun puzzle.
To begin, here's how you can create your "random" inputs:
Random rng = new Random();
const string vowels = "AEIOU";
const string consonants = "BCDFGHJKLMNPQRSTVWXYZ";
string CreatePuzzle(int vowelCount, int consonantCount){
var result = new StringBuilder(vowelCount + consonantCount);
for (int i = 0; i < vowelCount; i++) {
result.Append(vowels[rng.Next(5)]);
}
for (int i = 0; i < consonantCount; i++) {
result.Append(consonants[rng.Next(21)]);
}
return result.ToString();
}
Then you'll need to create all permutations of these letters. This is a great job for recursion. The following code is an implementation of Heap's Algorithm that I found at http://www.cut-the-knot.org/do_you_know/AllPerm.shtml. Another helpful resource is http://www.codeproject.com/KB/recipes/Combinatorics.aspx
/// <summary>
/// Returns all permutations of the puzzle.
/// Uses "Heap's Algorithm" found at http://www.cut-the-knot.org/do_you_know/AllPerm.shtml
/// </summary>
IEnumerable<string> CreatePermutations(string puzzle) {
// It is easier to manipulate an array; start off the recursion:
return CreatePermutations(puzzle.ToCharArray(), puzzle.Length);
}
IEnumerable<string> CreatePermutations(char[] puzzle, int n) {
if (n == 0) {
// Convert the char array to a string and return it:
yield return new string(puzzle);
} else {
// Return the sub-string:
if (n < puzzle.Length) {
yield return new string(puzzle, n, puzzle.Length - n);
}
// Create all permutations:
for (int i = 0; i < n; i++) {
// Use recursion, and pass-through the values:
foreach (string perm in CreatePermutations(puzzle, n-1)) {
yield return perm;
}
// Create each permutation by swapping characters: (Heap's Algorithm)
int swap = (n % 2 == 1) ? 0 : i;
char temp = puzzle[n-1];
puzzle[n-1] = puzzle[swap];
puzzle[swap] = temp;
}
}
}
Note that this algorithm doesn't check for duplicates, so an input like "AAA" will still result in 6 permutations. Therefore, it might make sense to call .Distinct() on the results (although the CodeProject article has an algorithm that skips duplicates, but is more complicated).
The final step, as you stated, is to check all permutations against your dictionary.
Optimizations
This solution is fairly simple, and will probably work really well if your puzzles remain small. However, it is definitely a "brute force" kind of method, and as the puzzle gets bigger, performance drops exponentially!
I'm trying to figure out the time complexity of a function that I wrote (it generates a power set for a given string):
public static HashSet<string> GeneratePowerSet(string input)
{
HashSet<string> powerSet = new HashSet<string>();
if (string.IsNullOrEmpty(input))
return powerSet;
int powSetSize = (int)Math.Pow(2.0, (double)input.Length);
// Start at 1 to skip the empty string case
for (int i = 1; i < powSetSize; i++)
{
string str = Convert.ToString(i, 2);
string pset = str;
for (int k = str.Length; k < input.Length; k++)
{
pset = "0" + pset;
}
string set = string.Empty;
for (int j = 0; j < pset.Length; j++)
{
if (pset[j] == '1')
{
set = string.Concat(set, input[j].ToString());
}
}
powerSet.Add(set);
}
return powerSet;
}
So my attempt is this:
let the size of the input string be n
in the outer for loop, must iterate 2^n times (because the set size is 2^n).
in the inner for loop, we must iterate 2*n times (at worst).
1. So Big-O would be O((2^n)*n) (since we drop the constant 2)... is that correct?
And n*(2^n) is worse than n^2.
if n = 4 then
(4*(2^4)) = 64
(4^2) = 16
if n = 100 then
(10*(2^10)) = 10240
(10^2) = 100
2. Is there a faster way to generate a power set, or is this about optimal?
A comment:
the above function is part of an interview question where the program is supposed to take in a string, then print out the words in the dictionary whose letters are an anagram subset of the input string (e.g. Input: tabrcoz Output: boat, car, cat, etc.). The interviewer claims that a n*m implementation is trivial (where n is the length of the string and m is the number of words in the dictionary), but I don't think you can find valid sub-strings of a given string. It seems that the interviewer is incorrect.
I was given the same interview question when I interviewed at Microsoft back in 1995. Basically the problem is to implement a simple Scrabble playing algorithm.
You are barking up completely the wrong tree with this idea of generating the power set. Nice thought, clearly way too expensive. Abandon it and find the right answer.
Here's a hint: run an analysis pass over the dictionary that builds a new data structure more amenable to efficiently solving the problem you actually have to solve. With an optimized dictionary you should be able to achieve O(nm). With a more cleverly built data structure you can probably do even better than that.
2. Is there a faster way to generate a power set, or is this about optimal?
Your algorithm is reasonable, but your string handling could use improvement.
string str = Convert.ToString(i, 2);
string pset = str;
for (int k = str.Length; k < input.Length; k++)
{
pset = "0" + pset;
}
All you're doing here is setting up a bitfield, but using a string. Just skip this, and use variable i directly.
for (int j = 0; j < input.Length; j++)
{
if (i & (1 << j))
{
When you build the string, use a StringBuilder, not creating multiple strings.
// At the beginning of the method
StringBuilder set = new StringBuilder(input.Length);
...
// Inside the loop
set.Clear();
...
set.Append(input[j]);
...
powerSet.Add(set.ToString());
Will any of this change the complexity of your algorithm? No. But it will significantly reduce the number of extra String objects you create, which will provide you a good speedup.