I want to insert a space every 34 characters in a string
public string MySplit()
{
string SplitThis = "aaaaaaaaaaaa"; // assume that string has more than 34 chars
string[] array = new string[SplitThis .Length / 34];
for (int i = 1; i <= array.Length; i++)
{
SplitThis .Insert(i * 34, " ");
}
return SplitThis;
}
when I quickwatch "SplitThis .Insert(i * 34, " ");" I can see the space but the resultant string do not show the space. Why?
You are throwing away the result of the insert
Try
SplitThis = SplitThis.Insert(i*34, " ");
But there might be other logic errors in your code because you are amending the same string as you are working one and have calculated the number of iterations based on the length of the string, which is ignoring the fact that the length of the string is changing.
Related
I trying to split a string with Substring(), and I am having a problem I keep getting crashes with certin values.The problematic lane is(according to the "debugging" i tried):
string sub = str.Substring(beg,i);
and the whole code is :
static void Prints(string str)
{
int beg = 0;
for (int i = 0; i < str.Length; i++)
{
if (str[i] == '*')
{
Console.WriteLine(i);
//Console.WriteLine("before");
string sub = str.Substring(beg,i);
//Console.WriteLine("after");
beg = i+1;
if (sub.Length % 2 == 0)
{
Console.WriteLine(sub.Length/2);
int n = sub.Length / 2;
Console.WriteLine("{0} {1}", sub[n-1], sub[n]);
}
else
{
int n = sub.Length / 2;
Console.WriteLine(sub[n]);
}
The eror happens when the input is :
hi*its*
thats the output:
h i
Unhandled Exception: System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
at System.String.Substring(Int32 startIndex, Int32 length)
at _39.Program.Prints(String str) in D:\12\39\Program.cs:line 36
at _39.Program.Main(String[] args) in D:\12\39\Program.cs:line 13
I know there might be a better way using split() but I still want to understand what cause the eror.
Thanks in advance
Doron.
The problem is that you're not subtracting the distance you are into the string from the overall length.
If you look at the debug output you will find that:
str.Substring(3, 1) = "i"
str.Substring(3, 2) = "it"
str.Substring(3, 3) = "its"
str.Substring(3, 4) = "its*"
str.Substring(3, 5) = // Error! You're beyond the end of the string.
So clearly you are attempting to pull (in your example) 6 characters from the string starting at position 3. This would require an input string with total length 10 or more (as substring is Zero Index based). Your input string is only 7 chars long.
Try tokenizing your string. As soon as you try manually tokenizing using indices and counting things go wrong. Tokenizing is a god send :)
Good Luck!
I'm trying to add spaces between characters in a string in c#... Any advice would be very much appreciated.. Thanks
using System;
namespace nameReverser
{
class Program{
public static void Main(string[] args )
{ Console.WriteLine("Magical Name Reverser");
//User enters name
Console.WriteLine("Please Enter Your Name:");
string name = Console.ReadLine();
char[] cArray = name.ToCharArray();
string nameReversed = String.Empty;
for (int i= cArray.Length - 1; i>-1; i--)
{
nameReversed +=cArray[i];
}
Console.WriteLine("Your name in reverse order is:");
Console.WriteLine(nameReversed);
}
}
}
You can use String.Join to get a new string from array having a single space as separator. To print it in reverse order you can use Array.Reverse() hence your whole code will be like the following:
Console.WriteLine("Magical Name Reverser");
Console.WriteLine("Please Enter Your Name:");
string name = Console.ReadLine();
char[] cArray = name.ToCharArray();
Array.Reverse(cArray);
string resultString = String.Join(" ", cArray);
Console.WriteLine(resultString );
Console.WriteLine("Your name in reverse order is:");
Can be done in one-go
strResult= String.Join(" ", name.Reverse());
In addition to un-lucky's answer which adds spaces after each letter you can as well use the Insert() method of a string to add a space at a certain index
Example:
name = "Rudolf";
name.Insert (1, " ");
results to "R udolf"
Something like this
strResult= yourString(" ", name.Reverse());
Normally, I would recommend one of the other answers, if you only want to insert spaces into the string.
But in your example code, since you are looping through the string anyway, you can combine the reversal operation with the space insertion operation:
// ....
for (int i = cArray.Length - 1; i > -1; i--)
{
nameReversed += cArray[i] + " ";
}
// ...
Better yet, as suggested in the comments: if you are going to add to a string repeatedly, consider using a StringBuilder:
StringBuilder reverseBuilder;
for (int i = cArray.Length - 1; i > -1; i--)
{
reverseBuilder.Append(cArray[i]);
reverseBuilder.Append(' ');
}
// ...
nameReversed = reverseBuilder.ToString();
Slightly off subject...
If you want to add spaces between characters in a fixed width number like a time, you can also use the string format syntax:
int time = 1204; //represents 12:04
int hh = time / 100;
int mm = time - hh * 100;
string result = string.Format("{0:0 0} : {1:0 0}", hh, mm);
//result is 1 2 : 0 4
I have problem with adding a Zero-padding with for loop... here is my code:
class Program
{
static void Main(string[] args)
{
string str = "12";
for (var i = 1; i <= 6; i++)
{
Console.WriteLine(str.PadLeft(i, '0'));
Console.ReadLine();
}
}
}
Output of this is:
12
12
012
0012
00012
000012
Why are first two values repeated?
The output that I whant to get is:
12
012
0012
00012
000012
tnx for help
From String.PadLeft(Int32, Char);
A new string that is equivalent to this instance, but right-aligned
and padded on the left with as many paddingChar characters as needed
to create a length of totalWidth. However, if totalWidth is less than
the length of this instance, the method returns a reference to the
existing instance. If totalWidth is equal to the length of this instance, the method returns a new string that is identical to this instance.
That's why when i is 1 or 2, your result will be the same as 12.
You should start your loop int i = 2 instead of int i = 1.
string str = "12";
for(var i = 2; i <= 6; i++)
{
Console.WriteLine(str.PadLeft(i, '0'));
}
Output will be;
12
012
0012
00012
000012
Here a demonstration.
By the way, Console.ReadLine() seems pointless in your case since you don't read anything in your console.
Padleft takes the string and adds zeros to the left up to the length of i.
Example:
string str = "12";
str.PadLeft(1, '0') // 12
str.PadLeft(2, '0') // 12
str.PadLeft(3, '0') // 012
str.PadLeft(4, '0') // 0012
First parameter of the PadLeft method is the total lenght of the string.Since the length of your string is 2, it only add zeros to the left when i becomes 3.
If you start i from 2 then you will get the expected result.
I'm trying to write strings with spaces into a listbox, and keep them aligned.
Here is the code:
List<String> treeNames = new List<String>();
int counter = 1;
treeNames.Add("Input ");
treeNames.Add("Output ");
treeNames.Add("Sequence Type ");
foreach (String currentData in treeNames)
{
listBox1.Items.Add(currentData + " - " + counter.ToString());
counter+=1;
}
Here's what I hope to achieve:
Input - 1
Output - 2
Sequence Type - 3
Instead, I'm getting:
Input - 1
Output - 2
Sequence Type - 3
Any ideas how can I align them?
foreach (String currentData in treeNames)
{
listBox1.Items.Add(String.Format("{0, -20} {1, 10}", currentData, ("- " + counter.ToString())));
counter += 1;
}
You can use String.PadRight method which returns a new string that left-aligns the characters in the string by padding them with spaces on the right for a specified total length.
Let's say you have 20 character maximum length for a name:
public String stringHighscore()
{
return name + name.PadRight(20 - name.Length) + "\t\t\t" + score.ToString();
}
If your name's length is 13, this will add 7 space characters. If your name's length is 9, this will add 11 space characters. That way all your name's lengths will equal 20 at the end.
I have five strings like below,
ABBCCD
ABBDCD
ABBDCD
ABBECD
ABBDCD
all the strings are basically same except for the fourth characters. But only the character that appears maximum time will take the place. For example here D was placed 3 times in the fourth position. So, the final string will be ABBDCD. I wrote following code, but it seemed to be less efficient in terms of time. Because this function can be called million times. What should I do to improve the performance?
Here changedString is the string to be matched with other 5 strings. If Any position of the changed string is not matched with other four, then the maxmum occured character will be placed on changedString.
len is the length of the strings which is same for all strings.
for (int i = 0; i < len;i++ )
{
String findDuplicate = string.Empty + changedString[i] + overlapStr[0][i] + overlapStr[1][i] + overlapStr[2][i] +
overlapStr[3][i] + overlapStr[4][i];
char c = findDuplicate.GroupBy(x => x).OrderByDescending(x => x.Count()).First().Key;
if(c!=changedString[i])
{
if (i > 0)
{
changedString = changedString.Substring(0, i) + c +
changedString.Substring(i + 1, changedString.Length - i - 1);
}
else
{
changedString = c + changedString.Substring(i + 1, changedString.Length - 1);
}
}
//string cleanString = new string(findDuplicate.ToCharArray().Distinct().ToArray());
}
I'm not quite sure what you are going to do, but if it is about sorting strings by some n-th character, then the best way is to use Counting Sort http://en.wikipedia.org/wiki/Counting_sort It is used for sorting array of small integers and is quite fine for chars. It has linear O(n) time. The main idea is that if you know all your possible elements (looks like they can be only A-Z here) then you can create an additional array and count them. For your example it will be {0, 0, 1 ,3 , 1, 0,...} if we use 0 for 'A', 1 for 'B' and so on.
There is a function that might help performance-wise as it runs five times faster. The idea is to count occurrences yourself using a dictionary to convert character to a position into counting array, increment value at this position and check if it is greater than previously highest number of occurrences. If it is, current character is top and is stored as result. This repeats for each string in overlapStr and for each position within the strings. Please read comments inside code to see details.
string HighestOccurrenceByPosition(string[] overlapStr)
{
int len = overlapStr[0].Length;
// Dictionary transforms character to offset into counting array
Dictionary<char, int> char2offset = new Dictionary<char, int>();
// Counting array. Each character has an entry here
int[] counters = new int[overlapStr.Length];
// Highest occurrence characters found so far
char[] topChars = new char[len];
for (int i = 0; i < len; ++i)
{
char2offset.Clear();
// faster! char2offset = new Dictionary<char, int>();
// Highest number of occurrences at the moment
int highestCount = 0;
// Allocation of counters - as previously unseen character arrives
// it is given a slot at this offset
int lastOffset = 0;
// Current offset into "counters"
int offset = 0;
// Small optimization. As your data seems very similar, this helps
// to reduce number of expensive calls to TryGetValue
// You might need to remove this optimization if you don't have
// unused value of char in your dataset
char lastChar = (char)0;
for (int j = 0; j < overlapStr.Length; ++ j)
{
char thisChar = overlapStr[j][i];
// If this is the same character as last one
// Offset already points to correct cell in "counters"
if (lastChar != thisChar)
{
// Get offset
if (!char2offset.TryGetValue(thisChar, out offset))
{
// First time seen - allocate & initialize cell
offset = lastOffset;
counters[offset] = 0;
// Map character to this cell
char2offset[thisChar] = lastOffset++;
}
// This is now last character
lastChar = thisChar;
}
// increment and get count for character
int charCount = ++counters[offset];
// This is now highestCount.
// TopChars receives current character
if (charCount > highestCount)
{
highestCount = charCount;
topChars[i] = thisChar;
}
}
}
return new string(topChars);
}
P.S. This is certainly not the best solution. But as it is significantly faster than original I thought I should help out.