Appending sequential characters to StringBuilder [duplicate] - c#

This question already has answers here:
How to convert a column number (e.g. 127) into an Excel column (e.g. AA)
(60 answers)
Closed 9 years ago.
I am trying to append sequential characters: A, B, ... AA, AB, ... to the beginning a a stringbuilder type. The problem I am having is that it will append all ASCII characters and not double characters. My code looks like this:
string prefix = null;
System.Text.StringBuilder text = new System.Text.StringBuilder();
for (j = 0; j < genList.Count; j++)
{
prefix = "." + Convert.ToChart(j + 65).ToString();
text.Append(prefix + genList[j]);
}

What you really want is something that will output an integer in base-26, using the letters A through Z as digits. So 0 corresponds to A, 25 is Z, 26 is AA, etc.
const string digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string ToBase26(int i)
{
StringBuilder sb = new StringBuilder();
do
{
sb.Append(digits[i % 26]);
i /= 26;
} while (i != 0);
// The digits are backwards. Reverse them.
return new string(sb.ToString.Reverse());
}
That's not the most optimum way to do it, but it'll work.
To output A, B, C, ... AA, AB, AC ... BA, etc:
for (int i = 0; i < Count; ++i)
{
Console.WriteLine(ToBase26(i));
}

Related

what is this line meaning in C# [duplicate]

This question already has answers here:
c# Ternary operator
(2 answers)
Closed 4 days ago.
im new at c# and to day i met a line that i dont understand, i hope can find the answer in here
public static void Main()
{
string output = String.Join(" ", GetAlphabet(true).Where( letter =>
letter.CompareTo("M") >= 0));
Console.WriteLine(output);
}
private static List<string> GetAlphabet(bool upper)
{
List<string> alphabet = new List<string>();
int charValue = upper ? 65 : 97;
for (int ctr = 0; ctr <= 25; ctr++)
alphabet.Add(((char)(charValue + ctr)).ToString());
return alphabet;
}```
the code i didnt understand :
int charValue = upper ? 65 : 97;
i want to know what it mean
Every character has an integer value. If you have a look at an ASCII table you see that the integer value of A is 65 and for a it's 97.
In your code that is the starting value and then you have a for loop which iterates over all 26 letters. Then this integer value will be parsed to the corresponding ASCII char with ((char)(charValue + ctr)).ToString().
So 65, 66, 67, ... will be parsed to A, B, C, ...

Finding the longest word (and write it out) in string without split, distinct and foreach [duplicate]

This question already has answers here:
Finding longest word in string
(4 answers)
Closed 3 years ago.
I got an assignment to make a method to find the longest word in a string without split, distinct and foreach.
I was able to split the words and count the length but I am stuck on how can I actually compare and write them out.
static void Main(string[] args)
{
String s1 = "Alex has 2 hands.";
longestWord(s1);
Console.
}
static void longestWord(String s1)
{
char emp = ' ';
int count = 0;
char[] ee = s1.ToCharArray();
for (int i = 0; i < ee.Length; i++)
{
if (ee[i] == emp || ee[i] == '.')
{
count++;
Console.Write(" " + (count-1));
Console.WriteLine();
count = 0;
}
else
{
Console.Write(ee[i]);
count++;
}
}
}
The output right now looks like this:
Alex 4
has 3
2 1
hands 5
I am pretty sure I would be able to get only the longest number to show by comparing count before reset with temp int but how to write out the word with it.
Or if there is a easier way which probably is.
You are already on a good way. Instead of directly printing the words, store the length and position of the longest word and print it at the end. Like so:
static void longestWord(String s1)
{
char emp = ' ';
int longestLength = 0;
int longestStart = 0;
int currentStart = 0;
for (int i = 0; i < s1.Length; i++)
{
if (s1[i] == emp || s1[i] == '.')
{
// calculate the current word length
int currentLength = i - currentStart;
// test if this is longer than the currently longest
if(currentLength > longestLength)
{
longestLength = currentLength;
longestStart = currentStart;
}
// a new word starts at the next character
currentStart = i + 1;
}
}
// print the longest word
Console.WriteLine($"Longest word has length {longestLength}: \"{s1.Substring(longestStart, longestLength)}\"");
}
There is no need for the .ToCharArray(). You can access the string directly.
I will question whether you are actually supposed to treat "2" as a word and count it at all. Using regular expressions will allow you to approach the problem using a LINQ one-liner:
static void Main(string[] args)
{
String s1 = "Alex has 2 hands.";
var word = longestWord(s1);
Console.WriteLine(word);
//Console.ReadLine();
}
static string longestWord(string s1) {
return Regex.Matches(s1,"[A-Za-z]+") // find all sequences containing alphabetical characters, you can add numberas as well: [A-Za-z0-9]
.Cast<Match>() // cast results to Enumberable<Match> so we can apply LINQ to it
.OrderByDescending(m => m.Length) // luckily for us, Match comes with Length, so we just sort our results by it
.Select(m => m.Value) // instead of picking up everything, we only want the actual word
.First(); // since we ordered by descending - first item will be the longest word
}
You can store for every word the chars in new list of chars (list for dynamic length)
and if the new word is longer of the prev long word convert it to string.
If you have two word in same length it will take the first.
If you want the last change the "maxLength < count" to "maxLength <= count"
static string longestWord(String s1)
{
char emp = ' ';
int count = 0;
int maxLength = 0;
string maxWord = string.Empty;
List<char> newWord = new List<char>();
char[] ee = s1.ToCharArray();
for (int i = 0; i < ee.Length; i++)
{
if (ee[i] == emp || ee[i] == '.')
{
if (maxLength < count)
{
maxLength = count;
maxWord = new string(newWord.ToArray());
}
count = 0;
newWord = new List<char>();
}
else
{
newWord.Add(ee[i]);
count++;
}
}
return maxWord;
}

Find all possible combinations of word with and without hyphens

For a string that may have zero or more hyphens in it, I need to extract all the different possibilities with and without hyphens.
For example, the string "A-B" would result in "A-B" and "AB" (two possibilities).
The string "A-B-C" would result in "A-B-C", "AB-C", "A-BC" and "ABC" (four possibilities).
The string "A-B-C-D" would result in "A-B-C-D", "AB-C-D", "A-BC-D", "A-B-CD", "AB-CD", "ABC-D", "A-BCD" and "ABCD" (eight possibilities).
...etc, etc.
I've experimented with some nested loops but haven't been able to get anywhere near the desired result. I suspect I need something recursive unless there is some simple solution I am overlooking.
NB. This is to build a SQL query (shame that SQL Server does't have MySQL's REGEXP pattern matching).
Here is one attempt I was working on. This might work if I do this recursively.
string keyword = "A-B-C-D";
List<int> hyphens = new List<int>();
int pos = keyword.IndexOf('-');
while (pos != -1)
{
hyphens.Add(pos);
pos = keyword.IndexOf('-', pos + 1);
}
for (int i = 0; i < hyphens.Count(); i++)
{
string result = keyword.Substring(0, hyphens[i]) + keyword.Substring(hyphens[i] + 1);
Response.Write("<p>" + result);
}
A B C D are words of varying length.
Take a look at your sample cases. Have you noticed a pattern?
With 1 hyphen there are 2 possibilities.
With 2 hyphens there are 4 possibilities.
With 3 hyphens there are 8 possibilities.
The number of possibilities is 2n.
This is literally exponential growth, so if there are too many hyphens in the string, it will quickly become infeasible to print them all. (With just 30 hyphens there are over a billion combinations!)
That said, for smaller numbers of hyphens it might be interesting to generate a list. To do this, you can think of each hyphen as a bit in a binary number. If the bit is 1, the hyphen is present, otherwise it is not. So this suggests a fairly straightforward solution:
Split the original string on the hyphens
Let n = the number of hyphens
Count from 2n - 1 down to 0. Treat this counter as a bitmask.
For each count begin building a string starting with the first part.
Concatenate each of the remaining parts to the string in order, preceded by a hyphen only if the corresponding bit in the bitmask is set.
Add the resulting string to the output and continue until the counter is exhausted.
Translated to code we have:
public static IEnumerable<string> EnumerateHyphenatedStrings(string s)
{
string[] parts = s.Split('-');
int n = parts.Length - 1;
if (n > 30) throw new Exception("too many hyphens");
for (int m = (1 << n) - 1; m >= 0; m--)
{
StringBuilder sb = new StringBuilder(parts[0]);
for (int i = 1; i <= n; i++)
{
if ((m & (1 << (i - 1))) > 0) sb.Append('-');
sb.Append(parts[i]);
}
yield return sb.ToString();
}
}
Fiddle: https://dotnetfiddle.net/ne3N8f
You should be able to track each hyphen position, and basically say its either there or not there. Loop through all the combinations, and you got all your strings. I found the easiest way to track it was using a binary, since its easy to add those with Convert.ToInt32
I came up with this:
string keyword = "A-B-C-D";
string[] keywordSplit = keyword.Split('-');
int combinations = Convert.ToInt32(Math.Pow(2.0, keywordSplit.Length - 1.0));
List<string> results = new List<string>();
for (int j = 0; j < combinations; j++)
{
string result = "";
string hyphenAdded = Convert.ToString(j, 2).PadLeft(keywordSplit.Length - 1, '0');
// Generate string
for (int i = 0; i < keywordSplit.Length; i++)
{
result += keywordSplit[i] +
((i < keywordSplit.Length - 1) && (hyphenAdded[i].Equals('1')) ? "-" : "");
}
results.Add(result);
}
This works for me:
Func<IEnumerable<string>, IEnumerable<string>> expand = null;
expand = xs =>
{
if (xs != null && xs.Any())
{
var head = xs.First();
if (xs.Skip(1).Any())
{
return expand(xs.Skip(1)).SelectMany(tail => new []
{
head + tail,
head + "-" + tail
});
}
else
{
return new [] { head };
}
}
else
{
return Enumerable.Empty<string>();
}
};
var keyword = "A-B-C-D";
var parts = keyword.Split('-');
var results = expand(parts);
I get:
ABCD
A-BCD
AB-CD
A-B-CD
ABC-D
A-BC-D
AB-C-D
A-B-C-D
I've tested this code and it is working as specified in the question. I stored the strings in a List<string>.
string str = "AB-C-D-EF-G-HI";
string[] splitted = str.Split('-');
List<string> finalList = new List<string>();
string temp = "";
for (int i = 0; i < splitted.Length; i++)
{
temp += splitted[i];
}
finalList.Add(temp);
temp = "";
for (int diff = 0; diff < splitted.Length-1; diff++)
{
for (int start = 1, limit = start + diff; limit < splitted.Length; start++, limit++)
{
int i = 0;
while (i < start)
{
temp += splitted[i++];
}
while (i <= limit)
{
temp += "-";
temp += splitted[i++];
}
while (i < splitted.Length)
{
temp += splitted[i++];
}
finalList.Add(temp);
temp = "";
}
}
I'm not sure your question is entirely well defined (i.e. could you have something like A-BCD-EF-G-H?). For "fully" hyphenated strings (A-B-C-D-...-Z), something like this should do:
string toParse = "A-B-C-D";
char[] toParseChars = toPase.toCharArray();
string result = "";
string binary;
for(int i = 0; i < (int)Math.pow(2, toParse.Length/2); i++) { // Number of subsets of an n-elt set is 2^n
binary = Convert.ToString(i, 2);
while (binary.Length < toParse.Length/2) {
binary = "0" + binary;
}
char[] binChars = binary.ToCharArray();
for (int k = 0; k < binChars.Length; k++) {
result += toParseChars[k*2].ToString();
if (binChars[k] == '1') {
result += "-";
}
}
result += toParseChars[toParseChars.Length-1];
Console.WriteLine(result);
}
The idea here is that we want to create a binary word for each possible hyphen. So, if we have A-B-C-D (three hyphens), we create binary words 000, 001, 010, 011, 100, 101, 110, and 111. Note that if we have n hyphens, we need 2^n binary words.
Then each word maps to the output you desire by inserting the hyphen where we have a '1' in our word (000 -> ABCD, 001 -> ABC-D, 010 -> AB-CD, etc). I didn't test the code above, but this is at least one way to solve the problem for fully hyphenated words.
Disclaimer: I didn't actually test the code

Place every n-th character in string at n-7 position

I have string with 0's and 1's. It looks like this:
1110011011010000...
With spaces for better visualisation (original string from my program doesn't contain spaces)
11100110 11010000 ...
Every eight elements must be a letter of Unicode in binary.
What i need to do, is put every last 0 or 1 of each letter (every 8th element in full string) to the first place for this letter, so this string would be like this:
0111001101101000...
With spaces for better visualisation (original string from my program doesn't contain spaces)
01110011 01101000 ...
How can I do this in C#?
strings are immutable so i would use StringBuilder to move characters
var s = "1110011011010000";
var window = 8; // the tail of string which is shoreter than 8 symbols (if any) will be ignored
System.Text.StringBuilder sb = new System.Text.StringBuilder(s);
for(int i = 0; i <= s.Length-window; i=i+window)
{
char c = sb[i+window-1];
sb.Remove(i+window-1,1);
sb.Insert(i,c);
}
string result = sb.ToString();
Start by splitting your string into chunks of size eight (here is how).
This gives you an IEnumerable<string>. Take each string of length 8, and recombine its characters like this:
string orig = "11100110";
string res = orig.Substring(1)+orig[0];
Finally, merge back the parts processed in the above way to get your final string (here is how).
Here's my solution. The method ShiftChunkChars takes a string and integer which depicts the amount of characters in each "chunk". Beware that this method does not work if the input string's length is not divisible by chunkSize.
string ShiftChunkChars(string original, int chunkSize)
{
char[] buffer = new char[chunkSize];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < original.Length; i += chunkSize)
{
char[] chars = original.Substring(i, chunkSize).ToCharArray();
Array.Copy(chars, 0, buffer, 1, chunkSize - 1);
buffer[0] = chars[chunkSize - 1];
sb.Append(buffer);
}
return sb.ToString();
}
Examples:
1.
void Main()
{
int chunkSize = 8;
string s = "11100110110100000111001101101000";
ShiftChunkChars(s, chunkSize);
}
Output:
01110011011010001011100100110100
// Original with spaces: 11100110 11010000 01110011 01101000
// Result with spaces: 01110011 01101000 10111001 00110100
2.
void Main()
{
int chunkSize = 4;
string s = "11100110110100000111001101101000";
ShiftChunkChars(s, chunkSize);
}
Output:
01110011111000001011100100110100
// Original with spaces: 1110 0110 1101 0000 0111 0011 0110 1000
// Result with spaces: 0111 0011 1110 0000 1011 1001 0011 0100
You should be able to do this very simple with Regex:
string formattedBinary = Regex.Replace("0111001101101000", ".{8}", "$0 ");
Try with this. Not sure if I have undestood the question. In this case I looped twice because I had 16 chars.
string s = "1110011011010000";
char[] nc = s.ToCharArray();
for (int i = 0; i < 2; i++)
{
char tmp = nc[i * 8 + 7];
for (int j = 6; j > 0; j--)
{
nc[i * 8 + j + 1] = nc[i * 8 + j];
}
nc[i * 8] = tmp;
}
s = new string(nc);

Incrementing characters in a particular pattern in C#

The program should take in a parameter N and print out N + 1 lines.
I have to output something like this.
This is the output which I must get at N = 5
A //Increment by 0
AB //Increment by 1
ACE //Increment by 2
ADGJ //Increment by 3
AEIMQ //Increment by 4
The algorithm uses N as the number of characters to skip in between each add. So at N=3, it's A skip 3 to D, skip 3 to G, skip three to J.
And when the program runs out of upper case characters(i.e. When N is too big), it should start with lower case characters and if it runs out of lower case then it should again start with upper case and so on.
I am a novice to programming. And I dont really know where to start. I've been working around the loops for a while and still have no clue what-so-ever.
Here's another approach using a Char[], modulo, StringBuilder and a for-loop which increments by n for efficiency:
readonly static Char[] letters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToCharArray();
static String appendChars(int n)
{
int length = n + 1;
StringBuilder sBuilder = new StringBuilder("A", length);
for (int i = n; sBuilder.Length < length; i += n)
{
Char nextChar = letters[i % letters.Length];
sBuilder.Append(nextChar);
}
return sBuilder.ToString();
}
test your sample data:
int n = 5;
IEnumerable<String> allWords = Enumerable.Range(0, n).Select(i => appendChars(i));
Console.Write(string.Join(Environment.NewLine, allWords));
outputs:
A
AB
ACE
ADGJ
AEIMQ
Here's the demo: http://ideone.com/0sspY
Try This :
public string GetOutPut(int increment)
{
string alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string output = string.Empty;
for(int i=0; i<=increment; i++)
{
int index = i*increment;
if(index>alphabets.Length)
index = index % alphabets.Length;
output+= alphabets[index];
}
return output;
}
It's not clear how you get the number of lines that you want - because you said N+1 but your example gives only N lines.
The following can be used to generate each one of those individual lines, and the Algo method can be modified to generate n+1 lines by sticking the code in a while loop, decrementing n and len and using AppendLine on the StringBuilder:
char[] allowedChars = Enumerable.Range('A', 26).Concat(Enumerable.Range('a', 26))
.Select(i => (char)i).ToArray();
[TestMethod]
public void Test()
{
Assert.AreEqual("A", Algo(0, 1));
Assert.AreEqual("AB", Algo(1, 2));
Assert.AreEqual("ACE", Algo(2, 3));
Assert.AreEqual("ADGJ", Algo(3, 4));
Assert.AreEqual("AEIMQ", Algo(4, 5));
}
public string Algo(int n, int len)
{
StringBuilder sb = new StringBuilder();
int nextCharIndex = 0;
for (int f = 0; f < len; f++)
{
sb.Append(allowedChars[nextCharIndex]);
//the `%`, or mod, here wraps around the next character back to upper case
nextCharIndex = (nextCharIndex + n) % allowedChars.Length;
}
return sb.ToString();
}

Categories

Resources