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.
Related
I need to count how many times a binary input needs to rotate to get its original form again
for example
if i enter 10101 it needs for rotation to 5 cyclic shifts to become 10101 again
if i enter 010101 it needs for rotation to 2 cyclic shifts to become 010101 again
or
if i enter 111111 or 000000 it needs 1 cyclic shifts to become 111111 or 000000 again
my code
using System;
class Solution
{
public static void Main(string[] args)
{
var binarayInput = Console.ReadLine();
var a = binarayInput;
var b = binarayInput[^1] + binarayInput[..^1];
Console.WriteLine(b);
var count = 0;
while(a !=b){
b = binarayInput[^1] + binarayInput[..^1];
count ++;
}
Console.WriteLine(count);
}
}
Here's another approach:
We take the string, concatenate it onto itself once and then ask what the first index of the original string is in the new string (starting at 1; if we started at 0 it would always match because zero shifts always matches):
var s = "10101";
var shiftsNeeded = (s+s).IndexOf(s, 1);
It works like:
"1010110101".IndexOf("10101", 1)
Start at 1:
1010110101
10101 -> index 1? no
1010110101
10101 -> index 2? no
1010110101
10101 -> index 3? no
1010110101
10101 -> index 4? no
1010110101
10101 -> index 5? yes
Try this:
string originalInput = Console.ReadLine()+string.Empty;
Console.WriteLine($"Input: {originalInput}");
string current = string.Join(string.Empty, originalInput.Select(c => c));
for(var i=0; i<originalInput.Length; i+=1) {
var temp = CyclicShift(current);
Console.WriteLine($"Shift {i+1}: {temp}");
if(originalInput.Equals(temp)) {
Console.WriteLine($"Become original after {i+1} shifts.");
break;
}
current = temp;
}
string CyclicShift(string input) {
if(input.Length == 0) return string.Empty;
if(input.Length == 1) return input;
var newStr = input[^1] + input[..^1];
return newStr;
}
Test:
Input: 10101
Shift 1: 11010
Shift 2: 01101
Shift 3: 10110
Shift 4: 01011
Shift 5: 10101
Become original after 5 shifts.
Input: 010101
Shift 1: 101010
Shift 2: 010101
Become original after 2 shifts.
Input: 111111
Shift 1: 111111
Become original after 1 shifts.
If you are using .Net 6, you could take the advantage of .TakeLast() and .SkipLast() from System.Linq when temporarily "building" your rotated string.
using System;
using System.Linq;
class Solution
{
public static void Main(string[] args)
{
var binaryInput = Console.ReadLine();
var shifts = 1;
while (binaryInput != string.Join("", binaryInput.TakeLast(shifts).Concat(binaryInput.SkipLast(shifts))))
{
shifts++;
}
Console.WriteLine(shifts);
}
}
When e.g. shifts == 3, binaryInput.TakeLast(shifts) will take the 3 last chars of binaryInput (converted to an IEnumerable<char>, because that is the return value of .TakeLast() when it is called on a string), and binaryInput.SkipLast(shifts) will take all the chars of binaryInput but the three last (also converted to an IEnumerable<char>).
To stitch the two IEnumerable<char>s back together to a string again, I am using .Concat() to merge them into one IEnumerable<char>, and then string.Join() to convert it to a string that can be compared with binaryInput.
Fiddle to try it out here.
You don't have to make so much as one single substring/one extra allocation operation to complete this.
This method tests if a string shifted (right) by offset is equal to the string:
bool CircularEquals(string s, int offset){
for(int i = 0; i < s.Length; i++)
if(s[i] != s[(i+offset) % s.Length])
return false;
return true;
}
It works by conceptually establishing two pointers to the chars in the string and advancing them each by one. When the "shifted right" pointer falls off the end of the string a modulo wraps it around again
e.g. a shift of 2:
10101
^
^ 1 == 1, loop continues
10101
^
^ 0 == 0, loop continues
10101
^
^ 1 == 1, loop continues
10101
^
^ 0 != 1, returns false. 10101 doesn't work if shifted 2
You can test each shift:
var s = "10101";
for(int i = 1; i <= s.Length; i++){
if(CircularEquals(s,i))
Console.WriteLine("String " + s + " is identical after " + i + " shifts");
}
I have converted string to char[], but now when I try to get a total of all the numbers in the array, I get a wrong output. The goal is that if the user enters a number as a string e.g - 12, the output should be 3 i.e 1 + 2, another example - 123 should be 1+2+3 = 6.
I am new to coding. My apologies for any inconvienence.
static void Main(string[] args)
{
int sum = 0;
String num = Console.ReadLine();
char[] sep = num.ToCharArray();
for (int i = 0; i < sep.Length; i++)
{
sum += (sep[i]);
}
Console.WriteLine(sum);
Console.ReadLine();
}
You are currently adding ascii values. The ascii value of 1 is 49 and that of 2 Is 50... You need to use int.TryParse to convert from char to int.
int value;
for (int i = 0; i < sep.Length; i++)
{
if (int.TryParse (sep[i].ToString(),out value))
sum += value;
}
If you want to calculate sum of digits, you need to convert each char to int first. Char needs to be converted to string and then parsed into int. Your original code contains implicit conversion, which converts 1 and 2 into 49 and 50 (ASCII), thus the sum ends up being 99.
Try this code instead:
static void Main(string[] args)
{
int sum = 0;
String num = Console.ReadLine();
char[] sep = num.ToCharArray();
for (int i = 0; i < sep.Length; i++)
{
sum += int.Parse(sep[i].ToString());
}
Console.WriteLine(sum);
Console.ReadLine();
}
Just for fun here is a LINQ solution.
var sum = num.Select( c => int.Parse((string)c) ).Sum();
This solution takes advantage of the fact that a string is also an IEnumerable<char> and therefore can be treated as a list of characters.
The Select statement iterates over the characters and converts each one to an integer by supplying a lambda expression (that's the => stuff) that maps each character onto its integer equivalent. The symbol is typically prounced "goes to". You might pronounce the whole expression "C goes to whatever integer can be parsed from it."
Then we call Sum() to convert the resulting list of integers into a numeric sum.
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!
This is kind of a funky program. For some reason it works when the binary input is something like 101. Then it doesn't for 1000. This is kind of odd. Could someone please explain?
class Program
{
static void Main()
{
string binary = "xxx";
double decimalValue = 0;
Console.WriteLine("Enter in a binary number:");
binary = Console.ReadLine();
for (int i = 0; i < binary.Length; i++)
{
Console.WriteLine("Length is: {0}", binary.Length);
if (binary[i] == 49) //Look at that
decimalValue = decimalValue + Math.Pow(2, i);
}
Console.WriteLine("The decimal equivalent value is {0}", decimalValue);
Console.ReadLine();
}
}
The heart of it is of course
if (binary[i] == 49)
I'm just making it to teach myself some C#. Could someone tell me what to put on the right side other than 49, which is the ASCII number for "1". If I put "1" I get an error saying you can't compare a string to a char.
Any help would be appreciated. I don't want to use the pre-canned convert to binary method, because this is supposed to be a teachable moment.
You read the characters from the wrong end.
As was said immediately in the first comment to the question, by Lucas Trzesniewski, replace one use of i (not both) inside the for loop with binary.Length - 1 - i.
The reason why it works for "101" is that this is a palindrome (reads the same backwards).
Note: 49 is the ASCII code for '1'. It is more readable to use == '1' than == 49. However, both work equally well. In C# you get a char value if you use single quotes, as in '1', and you get a string object reference if you use double quotes, "1".
You should remove the stuff with "xxx". It has no function. Just dostring binary = Console.ReadLine();.
Instead of trying to add the value of each individual bit based on it's position you could take another approach: shift and add. In this approach you shift the current value to the left (by multiplying that value by 2) and adding the current bit.
For instance: the binary value 1010 becomes decimal 10 in four cycles:
value = 0
value *= 2 => value = 0
value += bit 1 => value = 1
value *= 2 => value = 2
value += bit 0 => value = 2
value *= 2 => value = 4
value += bit 1 => value = 5
value *= 2 => value = 10
value += bit 0 => value = 10
Or, in code:
using System;
public class Program
{
public static void Main()
{
string binary = "";
double decimalValue = 0;
Console.WriteLine("Enter in a binary number:");
binary = Console.ReadLine();
for (int i = 0; i < binary.Length; i++)
{
decimalValue *=2; // shift current value to the left
if (binary[i] == 49)
{
decimalValue += 1; // add current bit
}
Console.WriteLine("Current value: {0}", decimalValue);
}
Console.WriteLine("The decimal equivalent value is {0}", decimalValue);
Console.ReadLine();
}
}
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.