appending string horizontally in c# - c#

I am new to C# and trying a demo program in this program my intended output is:
Id 1 2 3 4 5 6 7 8 9
Roll # 1 2 3 4 5 6 7 8 9
and this is what I have tried :
static void Main(string[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append("Id ");
for (int i = 0; i < 10; i++)
{
sb.Append(i+" ");
}
sb.AppendLine();
sb.Append("Roll# ");
for (int i = 0; i < 10; i++)
{
sb.Append(i + " ");
}
Console.WriteLine(sb);
}
though it gives me desired output but here I have to iterate through for loop twice. Is there any way by which only iterating once I can get the same output, using some string formatting of C#?

This can be done without explicit looping, using Enumerable.Range to "generate a sequence of integral numbers within a specified range", along with string.Join() to concatenate the previously created range with the string " " :
// using System.Linq;
string range = string.Join(" ", Enumerable.Range(1, 10)); // "1 2 3 4 5 6 7 8 9 10"
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
If you really want to use a for loop to build your sequence, you can build your own Range method such as :
public static IEnumerable<int> Range(int min, int max)
{
if (min > max)
{
throw new ArgumentException("The min value can't be greater than the max");
}
for (int i = min; i <= max; i++)
{
yield return i;
}
}
And then Join like previously :
var range = string.Join(" ", Range(1, 10));
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
Or build an array/List/whatever collection and then use string.Join() :
var arr = new int [10];
for (int i = 1; i <= 10; i++)
{
arr[i - 1] = i;
}
string range = string.Join(" ", arr);
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");
Or directly build a string in the loop :
var sbRange = new StringBuilder();
for (int i = 1; i <= 10; i++)
{
sbRange.Append($"{i} ");
}
// You can use a string and trim it (there is a space in excess at the end)
string range = sbRange.ToString().Trim();
sb.AppendLine($"Id {range}");
sb.AppendLine($"Roll# {range}");

Instead of 1, use 2 StringBuilder instances:
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
sb1.Append("Id ");
sb2.Append("Roll# ");
for (int i = 0; i < 10; i++)
{
sb1.Append(i + " ");
sb2.Append(i + " ");
}
Console.WriteLine(sb1);
Console.WriteLine(sb2);

This will always require at least 3 loops:
One for the creation for the array.
One for each WriteLine.
At best you can have somebody elses code do the looping for you.
Unless you are interested in pulling stunts like manually inserting the Newline into a really long string, there is no way to save even a single loop. But such a thing is just unreliable and should not be atempted.
It honestly sounds a lot like a Speed Question, and for those we have the speed rant. You should read it either way, but can skip part 1.
The only improovement I can think of is building those strings with a stringbuilder. String concatenation in loops can be a bit troublesome. But on this scale it works either way.

Related

Numbers wont follow when shifting array to the left

Numbers can shift to the left => check.
Only the first number in the array follows, the rest disappears.
Example how it is right now:
Input array: 1 2 3 4 5 6
Input how many times to shift left: 3
Output: 4 5 6 1
How the Output should be: 4 5 6 1 2 3
Can someone help met with this probably simple solution which I can't find.
var str = Console.ReadLine();
int shift = Convert.ToInt32(Console.ReadLine());
var strArray = str.Split(' ');
var x = strArray[0];
for (var i = 0; i < strArray.Length - shift; i++)
{
strArray[i] = strArray[i + shift];
}
strArray[strArray.Length - shift] = x;
for (var i = 0; i <= strArray.Length - shift; i++)
{
Console.Write(strArray[i] + ' ');
}
You can use Linq to perform your shift, here is a simple method you can use
public int[] shiftRight(int[] array, int shift)
{
var result = new List<int>();
var toTake = array.Take(shift);
var toSkip = array.Skip(shift);
result.AddRange(toSkip);
result.AddRange(toTake);
return result.ToArray();
}
Here is quick fix for you. please check following code.
I shift element to left by 1 position you can change code as par your requirement.
Input array: 1 2 3 4 5 6
Input how many times to shift left: 1
Output : 2 3 4 5 6 1
int[] nums = {1, 2, 3, 4, 5, 6};
Console.WriteLine("\nArray1: [{0}]", string.Join(", ", nums));
var temp = nums[0];
for (var i = 0; i < nums.Length - 1; i++)
{
nums[i] = nums[i + 1];
}
nums[nums.Length - 1] = temp;
Console.WriteLine("\nAfter rotating array becomes: [{0}]", string.Join(", ", nums));
If this is only for strings and the wraparound is necessary I would suggest to use str.Substring(0,shift)
and append it to str.Substring(shift) (don't try to reinvent the weel)
(some info about the substring method: String.Substring )
otherwise the reason why it did not work is because you only saved the first value of the array instead of all the values you wanted to shift.
Do not save only the first value in the array
var x = strArray[0];
use
string[] x = new string[shift];
for (int i = 0; i < shift; i++)
{
x[i] = strArray[i];
}
instead so you collect all the values you need to add to the end.
EDIT: forgot the shifting
Shift the old data to the left
for (int i = 0; i < strArray.Length-shift; i++)
{
strArray[i] = strArray[i+shift];
}
And replace
strArray[strArray.Length - shift] = x;
for
for(int i = 0; i < x.Length; i++){
int newlocation = (strArray.Length - shift)+i;
strArray[newlocation] = x[i];
}
also replace the print loop for
Console.WriteLine(string.Join(" ", strArray));
its easier and makes it one line instead of three lines of code.
(also the docs for the Join function string.Join)

How to get every other character in a string in c#

so I'm working on this problem: https://www.hackerrank.com/challenges/30-review-loop/problem (it's in C#)
and so far I'm just trying to break it down piece by piece, and so far I was able to get it to show every other character, but I'm not sure how to concatenate each letter into a new string.
My code for the problem is as follows I've commented out the two for loops, because I felt like there was a more elegant solution to this than what I had, but I didn't want to lose where I was in case another path proved to be more challenging.
using System;
using System.Collections.Generic;
using System.IO;
class Solution {
static void Main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
int inputQTY = Int32.Parse(Console.ReadLine());
string input = Console.ReadLine(); // The example gives us the first word to be Hacker then the next word Rank on the next line, so the outputs would be Hce akr, and Rn ak respectively.
int strLen = input.Length;
char[] inputCharArray = input.ToCharArray();
string output = "";
/*
for (int j = 0; j < inputQTY; j++){
for (int i = 0; i < strLen; i++) {
if (j % 2 == 0 && i % 2 == 0) {
Console.WriteLine(inputCharArray[i]);
output = new string (new char[] {inputCharArray[i]});
Console.WriteLine(output);
Console.WriteLine("This is i: {0}", i);
Console.WriteLine("This is j: {0}", j);
Console.WriteLine("--------------");
Console.WriteLine("");
}
else {
Console.WriteLine("This is the next j part hopefully: {0}", j);
}
}
}*/
}
}
Like I understand I need to first step through the word, grab every other letter, then step through the word again and grab the remaining letters, then concatenate those letters into words, and concatenate those words into a sentence, so j would be the loop giving me the two words where I is the loop getting the two words put together..... but I'm having a difficult time wrapping my head around where I'm going wrong here. On top of this, I feel like there's another approach entirely that I'm missing, using commands I may not even know about.
Anyhoo any help is appreciated, hopefully I won't be so green after this. Thanks!
Ok so I ended up solving it with the following code, thank you for all your help everyone!
I ended up solving it with the following code (in C#):
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
class Solution {
static void Main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution */
int count = Int32.Parse(Console.ReadLine());
for (int k = 0; k < count; k++) {
char[] word = Console.ReadLine().ToCharArray();
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder();
for (int i = 0; i < word.Length; i+=2) {
sb1.Append(word[i]);
}
for (int j = 1; j < word.Length; j+=2) {
sb2.Append(word[j]);
}
Console.WriteLine(sb1 + " " + sb2);
}
}
}
LINQ version, updated to fix index error:
output = $"{new string(s.Where((x,i) => i % 2 == 0).ToArray())} {new string(s.Where((x,i) => i % 2 != 0).ToArray())}";
To explain, you're grabbing every character whose index in the string is evenly divisible by 2 and printing it, then every character in the string whose index is not evenly divisible by 2 and printing it.
Update:
Since I was asked for further explanation. First, here's the full code that runs successfully in the HackerRank challenge:
using System;
using System.Collections.Generic;
using System.Linq;
class Solution
{
static void Main(String[] args)
{
List<string> tests = new List<string>();
var testCount = int.Parse(Console.ReadLine());
for (var i = 0; i < testCount; i++)
{
tests.Add(Console.ReadLine());
}
foreach (var s in tests)
{
Console.WriteLine($"{new string(s.Where((x, i) => i % 2 == 0).ToArray())} {new string(s.Where((x, i) => i % 2 != 0).ToArray())}");
}
}
}
Regarding what each section of the code does:
i % 2 == 0
This is a test to see if a number is evenly divisible by two, or an even number.
s.Where((x,i) => i % 2 == 0)
This says, for the array of characters that make up the string 's', return all characters (the result is an IEnumerable) where that character's index (location in the string) is an even number.
new string(s.Where((x,i) => i % 2 == 0).ToArray())
This says to take that IEnumerable of characters with even numbered indexes and return them to an Array of characters. Then, create a new string out of that array of characters.
For the odd numbers, it's the same, but you use != 0 in the mod.
I used this simple method of appending to two StringBuilder objects
var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
int i = 0;
foreach (char c in input)
{
var sb = (i % 2 == 0 ? sb1 : sb2);
sb.Append(c);
i = i + 1;
}
output = sb1.ToString() + " " + sb2.ToString();
this is the long way..
int count = int.Parse(Console.ReadLine());
for(int k = 0; k < count; k++){
char[] inputChars = Console.ReadLine().ToCharArray();
char[] evenChars = new char[inputChars.Length % 2 == 0 ? inputChars.Length / 2 : (inputChars.Length + 1) / 2];
char[] oddChars = new char[inputChars.Length - evenChars.Length];
int evenIndex=0,oddIndex = 0;
for(int i = 0; i < inputChars.Length;i++)
if(i % 2 == 0)
evenChars[evenIndex++] = inputChars[i];
else
oddChars[oddIndex++] = inputChars[i];
Console.WriteLine(string.Format("{0} {1}",string.Concat(evenChars),string.Concat(oddChars)));
}
an alternative..
int count = int.Parse(Console.ReadLine());
for(int k = 0; k < count; k++){
string input = Console.ReadLine();
Enumerable.Range(0, input.Length)
.OrderBy(o => o % 2 != 0)
.Select(o => {
if(o == 1)
Console.Write(" ");
Console.Write(input[o]);
return input[o];
}).ToArray();
Console.Write("\n");
}

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

C# Program that converts decimal number to binary

So, I have to make a program that converts a decimal number to binary and prints it, but without using Convert. I got to a point where I can print out the number, but it's in reverse(for example: 12 comes out as 0011 instead of 1100), anyone has an idea how to fix that ? Here's my code:
Console.Write("Number = ");
int n = int.Parse(Console.ReadLine());
string counter = " ";
do
{
if (n % 2 == 0)
{
counter = "0";
}
else if (n % 2 != 0)
{
counter = "1";
}
Console.Write(counter);
n = n / 2;
}
while (n >= 1);
simple solution would be to add them at the beginning:
Console.Write("Number = ");
int n = int.Parse(Console.ReadLine());
string counter = "";
while (n >= 1)
{
counter = (n % 2) + counter;
n = n / 2;
}
Console.Write(counter);
You actually don't even need the if statement
Instead of write them inmediately you may insert them in a StringBuidler
var sb = new StringBuilder();
....
sb.Insert(0, counter);
And then use that StringBuilder
var result = sb.ToString();
You can reverse the String when you finish calculating it
You are generated the digits in the reverse order because you are starting with the least significiant digits when you use % 2 to determine the bit value. What you are doing is not bad though, as it is convenient way to determine the bits. All you have to do is reverse the output by collecting it until you have generated all of the bits then outputing everything in reverse order. ( I did not try to compile and run, may have a typo)
One easy solution is
System.Text.StringBuilder reversi = new System.Text.StringBuilder();
Then in your code replace
Console.Write(counter);
with
reversi.Append(counter);
Finally add the end of your loop, add code like this
string s = reversi.ToString();
for (int ii = s.Length-1; ii >= 0; --ii)
{
Console.Write(s[ii]);
}
There are better ways to do this, but this is easy to understand why it fixes your code -- It looks like you are trying to learn C#.
If I'm not mistaken
int value = 8;
string binary = Convert.ToString(value, 2);

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