Loop Count String (ex A to ABC) C# [duplicate] - c#

This question already has answers here:
Iterating through the Alphabet - C# a-caz
(10 answers)
Closed 6 years ago.
I am not sure how to search for this, or I would. What I need to do is count up with letters rather than numbers. the input will only contain letters and numbers, no spaces, or dashes.
For example, if the user enters "A" for start and "ABC" for end it would output, A, B, C,...AA, AB, AC,...ABC.
I can do it by breaking everything down to an array, increase, the last index, until "Z", then, increase the index, check if it is equals end, then loop again.When "Z" is hit and it has a number (treated as a string) start to loop through "0 - 9".
It just seems there would be an easier way, than what I am thinking. I seen one solution in Java that I could convert, but not fully understanding how it works SO Post it is using MOD and does not really compare values. This is just a small project for a computer lab, to generate NetBIOS names, for another program to use. All the names are sequential.
Thanks,
Dave

Dim array1 As String() = {"a", "b", "c"}
Dim array2 As String() = {"a", "b", "c"}
Dim result = array1.SelectMany(Function(f) array2, Function(f, a) New With {Key .first = f, Key .second = a})
Dim s As String = String.Empty
For i As Integer = 0 To result.Count - 1
s += result(i).first + result(i).second + " "
Next
MessageBox.Show(s)
output:
aa
ab
ac
ba
bb
bc
ca
cb
cc
I think this may be close to what you are after. Similar to a cross-join in SQL. This works in VB.Net but you can run a code converter
EDIT: (Ran through code converter (vb to c#), untested)
string[] array1 = {
"a",
"b",
"c"
};
string[] array2 = {
"a",
"b",
"c"
};
dynamic result = array1.SelectMany(f => array2, (f, a) => new {
first = f,
second = a
});
string s = string.Empty;
for (int i = 0; i <= result.Count - 1; i++) {
s += result(i).first + result(i).second + " ";
}
MessageBox.Show(s);
//=======================================================
//Service provided by Telerik (www.telerik.com)
//Conversion powered by NRefactory.
//Twitter: #telerik
//Facebook: facebook.com/telerik
//=======================================================

Related

Comparing two lists of Strings and counting the matches, possible performance problem

I want to count the amount of matches when comparing a List of Strings A with another List of Strings B. A contains elements from a Set Z and B is a subset of Z. A can contain duplicates but B cannot. I want duplicates to be counted individually so 2x match with the same element from B should yield 2 counts.
List A's strings contain a prefix which i decided to cut out but i could also leave the original string elements unmodified
Example:
List<string> A = {"a","b","c","a"}
List<string> B = {"a", "c"}
matches would be 3 (two times matched with a and once matched with c)
I have a solution that should work and in very rare cases it does work but my suspicion is that due to time constraints during execution it fails 90% of the time.
var _A = A.Select(str => str.ToLower()).ToList(); //B can be modified for this step to be not necessary but increases the length of each string element
_A = _A.Select(str => str.Replace(" ", "")).ToList(); //B can be modified for this step to be not necessary but increases the length of each string element
_A = _A.Select(x => x.Substring("drops".Length)).ToList(); //B can be modified for this step to be not necessary but increases the length of each string element
sum = _A.Where(x => B.Any(y => y.Equals(x))).Count();
This is O(A*B) if im not mistaken.
Is there anything more i can do to reduce the time complexity ?
You use an HashSet<string>. It is O(1) both in Add() and Contains().
var a = new[] { "a", "b", "c", "a" };
var b = new[] { "a", "c" };
var hs = new HashSet<string>(b);
var cnt = a.Count(x => hs.Contains(x));
This has a complexity of O(b+a), O(b) for the Add(), O(A) for the Contains().

How to parse the following string

I am trying to generate a formula which could be anything like this, this is just a sample,
A + B + C > D - A
Now, A, B, C, D, etc are Column Names of a sheet (like excel sheet) i will be accessing in memory.
I need to generate a Rule, like the above A + B + C > D - A which will decide what kind of values user can add in a Cell.
Currently this is how i have begun:
string toValidate = "A + B + C > D + E - A";
string lhs = "", rhs = "";
string[] comparisonOperators = new string[] { "=", ">", "<", "<>", "!=" };
char[] arithmeticOperators = { '+', '-', '/', '*' };
toValidate = toValidate.Replace(#" ", "");
for (int i = 0; i < comparisonOperators.Length; i++)
{
if (toValidate.Contains(comparisonOperators[i]))
{
operatorIndex = toValidate.IndexOf(comparisonOperators[i]);
break;
}
}
lhs = toValidate.Substring(0, operatorIndex);
rhs = toValidate.Substring(operatorIndex + 1);
string[] columnLhsList = lhs.Split(arithmeticOperators);
string[] columnRhsList = rhs.Split(arithmeticOperators);
However even though i have the strings as lhs and rhs and even my operator which > in the above code, i am not able to understand how can i apply the formula on the sheet itself. I just need to know which Column has which operator associated.
Since i have the individual column names, but not the operator before them, for e.g,
+ before A - before A in another case.
How do i parse the above please help.
It is, however, a very fun question if you want to make simple formula parsers like this yourself.
I advice you to check out this article, since it is very clearly written and understandable because of it.
Shunting-yard Algorithm
Personally, I would never try/dare to create my own formula expression parser. Instead, I would (and did) use one of the may available ones, e.g. NCalc over at CodePlex.com.
Using these tools, it is as easy as writing
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
to get your formula evaluated.
Usually such libraries are very solid, well tested and have a rich function set. It would take ages (if ever) to do such a high quality library on my own.
To further cite the NCalc website, you can even use variables like e.g.:
Expression e = new Expression("Round(Pow([Pi], 2) + Pow([Pi2], 2) + [X], 2)");
e.Parameters["Pi2"] = new Expression("Pi * [Pi]");
e.Parameters["X"] = 10;
e.EvaluateParameter +=
delegate(string name, ParameterArgs args)
{
if (name == "Pi")
args.Result = 3.14;
};
Debug.Assert(117.07 == e.Evaluate());

C# - find the position of a string inside a predefined string array

I have a predefined string array with the letters from A to Q :
string[] SkippedAreasArray = new string[] {"A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q"};
In a TextBox inside Windows Form the user can enter skippedAreas like this: A,B,C,D... there is validations and restrictions to use only letters and commas so the input is guaranteed to be in this format.
What I do is taking the user input and populate another string array:
string[] SkippedAreasFromForm = new string[17];
...
SkippedAreasFromForm = (txtSkippedAreas.Text).Split(',');
Now comes the tricky part for which I'm seeking assistance. The user must enter Number of areas for example - 3. Which mean he is working only with A, B, and C. If the number of areas was 2 then he can only use A and B if the number of areas was 4 then A, B, C and D are available and so on.
What I need is to check if in the array SkippedAreasFromForm which is populated with the user input there is an area that doesn't match the above criteria.
What this mean in terms of coding - I need to take every element from SkippedAreasFromForm, take it's integer value from the predefined SkippedAreasArray and see if this value is equal or greater (>=) of the value that he entered as `Number of areas. If there is an area which is outside the scope of the selected number an error should be shown.
What I have right now is :
foreach (string tempAreaValue in SkippedAreasFromForm)
{
for (int i = 0; i < SkippedAreasArray.Length; i++)
{
if (tempAreaValue == SkippedAreasArray[i])
{
if ((i + 1) > entity.AreasCnt)
{
MessageBox.Show("You must use areas only within the Number of Areas scope!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txtSkippedAreas.Focus();
return false;
}
}
}
}
For the few test I made it works. But first - at least for me it seems over complicated. Second - I'm not sure that this algorithm is working exactly as I need to or I'm just having correct results by luck. Third - I'm coding C# for 2months now and this seems to me like an excellent candidate for a LINQ expression - do you think it would be better using LINQ and I would appreciate a help in the transformation.
I think you're just looking for IndexOf:
int index = SkippedAreasArray.IndexOf(tempAreaValue);
if (index >= entity.AreasCnt)
{
...
}
(You might also want to check for index being -1, which would occur if the element wasn't in the list at all. Also, consider duplicates - can the user enter A, A, A?)
If you are looking for the elements in the array from start index to max string elements based on areaNumber, then:
int areaNumber = 4;
var result = SkippedAreasArray.Select((r, i) => new { Value = r, Index = i })
.Where(r => r.Index <= areaNumber - 1)
.Select(r => r.Value)
.ToArray();
For areaNumber 4 you will get "A", "B", "C", "D"
EDIT:
I'm looking if every element from the user input (which is array
A,C,H,Q..) is inside the area determined from the areNumber (from comment)
Suppose your userInputArray is:
string[] userInputArray = new string[] {"A", "C", "H", "Q"};
Then you can use Enumerable.Except in the following manner:
if(result.Except(userInputArray).Any())
{
//Invalid
}
else
{
//Valid
}

Permutation of a list of strings algorithm

I need help understanding how to write a permutation algorithm. (if this is even permutation, they have to be in order and use the same values).
List<string> str = new List<string>{"a", "b", "c", "d"};
How can I get a list of each permutation available in this list? For eg.
a, b, c, d
ab, c, d
ab, cd
abc, d
abcd
a, bc, d
a, bcd
a, b, cd
For some reason I cant find a pattern to start with. I'd also like to be able to disregard permutation when a joined string has a count of like X characters. So if X was 4, in that list, number 5 wouldn't exist and there would be 7 permutations.
private List<string> permute(List<string> values, int maxPermutation)
{
//alittle help on starting it would be great :)
}
I looked and read this, but he does not keep the order.
This is rather straightforward: you have three spots where you could either put a comma or to put nothing. There are eight combinations corresponding to 2^3 binary numbers.
For each number from 0 to 7, inclusive, produce a binary representation. Put a comma in each position where binary representation has 1; do not put comma where there's zero.
for (int m = 0 ; m != 8 ; m++) {
string s = "a";
if ((m & 1) != 0) s += ",";
s += "b";
if ((m & 2) != 0) s += ",";
s += "c";
if ((m & 4) != 0) s += ",";
s += "d";
Console.WriteLine(s);
}
You could take a recursive approach: Take the first letter, build all possible combinations starting with the second one (this is the recursion...) and prepend the first letter to each of them. Then take the first two letters together, recursively build all combinations starting with the third one. And so on ...
As for you additional requirement: If you want to exclude all "combinations" containing a string with X letters, just skip this number when constructing the first string.
The Binary approach above is correct and this is actually a partitioning problem (but not "The Partitioning Problem") and not a permutation problem.
http://en.wikipedia.org/wiki/Partition_of_a_set
Watch out because of the number of partitions grows faster than exponentially (e^e^n) so it will be really slow for large strings.
Try the following code. I haven't tested it, but I think it's what you are looking for.
List<string> str = new List<string>{ "a", "h", "q", "z", "b", "d" };
List<List<string>> combinations = combine(str.OrderBy(s=>s).ToList());
List<List<string>> combine(List<string> items)
{
List<List<string>> all = new List<List<string>>();
// For each index item in the items array
for(int i = 0; i < items.Length; i++)
{
// Create a new list of string
List<string> newEntry = new List<string>();
// Take first i items
newEntry.AddRange(items.Take(i));
// Concatenate the remaining items
newEntry.Add(String.concat(items.Skip(i)));
// Add these items to the main list
all.Add(newEntry);
// If this is not the last string in the list
if(i + 1 < items.Length)
{
// Process sub-strings
all.AddRange(combine(items.Skip(i + 1).ToList()));
}
}
return all;
}
If you need to generate combinations (or permutations or variations), then Combinatorics is a fantastic library.

Get all possible word combinations

I have a list of n words (let's say 26). Now I want to get a list of all possible combinations, but with a maximum of k words per row (let's say 5)
So when my word list is: aaa, bbb, ..., zzz
I want to get:
aaa
bbb
...
aaabbb
aaaccc
...
aaabbbcccdddeeefff
aaabbbcccdddeeeggg
...
I want to make it variable, so that it will work with any n or k value.
There should be no word be twice and every combinations needs to be taken (even if there are very much).
How could I achieve that?
EDIT:
Thank you for your answers. It is not an assignment. Is is just that I forgot the combinations of my password and I want to be sure that I have all combinations tested. Although I have not 26 password parts, but this made it easier to explain what I want.
If there are other people with the same problem, this link could be helpfull:
Generate word combination array in c#
i wrote simple a function to do this
private string allState(int index,string[] inStr)
{
string a = inStr[index].ToString();
int l = index+1;
int k = l;
var result = string.Empty;
var t = inStr.Length;
int i = index;
while (i < t)
{
string s = a;
for (int j = l; j < k; j++)
{
s += inStr[j].ToString();
}
result += s+",";
k++;
i++;
}
index++;
if(index<inStr.Length)
result += allState(index, inStr);
return result.TrimEnd(new char[] { ',' });
}
allState(0, new string[] { "a", "b", "c"})
You could take a look at this
However, if you need to get large numbers of combinations (in the tens of millions) you should use lazy evaluation for the generation of the combinations.

Categories