Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
C# code for reversing a string
I couldn't understand this part
arr[name.Length - i] = name[i - 1];
Let us have a name of 5 characters. so the value of the arr will be 4, right?
Then in the loop, the looping variable is also taking the same length, so its initial value will be 4, too.
In the first iteration, the value of arr[4 - 4] will be arr[0] and name[4 - 1] will be name[3], so the first index of arr is copied with the fourth index of name.
How is the original name stored in reversed order in arr?
static void Main(string[] args)
{
Console.Write("What is your name: ");
var name = Console.ReadLine();
var arr = new char[name.Length];
for (var i = name.Length; i > 0; i--)
arr[name.Length - i] = name[i - 1];
var reversed = new string(arr);
Console.WriteLine(reversed);
}
I've reproduced the image of original code here.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine("What is your name? ");
string name = Console.ReadLine();
var arr = new char[name.Length];
for (var i = name.Length; i > 0; i--){
arr[name.Length -1] = name[i-1];
}
var reversed = new string(arr);
Console.WriteLine(reversed);
}
}
It looks like the indexing is just off a little. You want to take the length of the name that you've entered (the end of it) and take the characters starting from the end back to the beginning of the word. Below I've changed a few variable names to add a little more meaning to the code.
public static void CorrectedMain()
{
Console.WriteLine("What is your name? ");
string name = Console.ReadLine();
char[] reversedLetters = new char[name.Length];
for (var i = name.Length; i > 0; i--){
reversedLetters[i-1] = name[name.Length -i ];
}
var reversed = new string(reversedLetters);
Console.WriteLine(reversed);
}
If you enter Thomas in the first block you get back T, if you run the code in the second block you will get back samohT.
Here is a fiddle of it.
https://dotnetfiddle.net/txwyd1
In answer to your question: Strings and arrays are zero-indexed. I.e. the first element is at index 0. The last is at Length - 1.
The code in your example is not very well-written. It breaks a couple of basic coding principles.
Iterate forwards, unless there is a very specific need to go backwards. In this case, there is not.
Use zero-based variables when doing any code involving strings and arrays.
The example breaks both these, and I think that's part of what it makes it hard to read, but let's try.
Looking at the iteration, if Length is 5 as you suggested then i starts at 5 and goes down to 1. When i is 5: (name.Length - i) = 0, and i - 1 = 4, so the array index 0 (the first in the array) gets the character at position 4 (which is the 5th character).
On the next iteration, i is 4: (name.Length - i) = 1, and i - 1 = 3, so the array index 1 (the second in the array) gets the character at position 3 (which is the 4th character).
And so on.
Here's a slightly nicer version of the same algorithm. Hopefully, it is a bit easier to read.
public static void Main()
{
Console.Write("What is your name: ");
string name = Console.ReadLine();
int n = name.Length;
char[] arr = new char[n];
for (int i = 0; i < n; i++)
arr[i] = name[n - 1 - i];
string reversed = new String(arr);
Console.WriteLine(reversed);
}
Related
My apologies if I didn't explain it clear the first time. I have edited my explanation further in bold below.
In the program below user enters a word and then enters a letter which the user would like to replace with any character. For instance, user enter's a word "Hello" and the replacement letter is "l" with "$". So "Hello" will become "He$$o". First, the goal is to find the location of "l" (example - 2,3) and then replace the element in that specific location.
I started by finding the location of "l" and storing it in a findIndex array. Every time I run the program I get "22222" stored in findIndex[] array. At this point, I am not even sure if I am even applying the right logic. Any advice will be appreciated! Please don't use LINQ.
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
int[] findIndex = new int[myString.Length];
for (int i = 0; i < myString.Length; i++)
{
findIndex[i] = myString.IndexOf(myCharacter, 0);
}
for (int i = 0; i < findIndex.Length; i++)
{
Console.Write(findIndex[i]);
}
}
This is probably what you want :
public static void RemoveSpecifiedCharacters()
{
Console.WriteLine("\nWrite a word/sentence: ");
string myString = Console.ReadLine();
Console.Write("Type the character you would like to replace: ");
string myCharacter = Console.ReadLine();
List<int> findIndex = new List<int>();
int offs = 0;
while (offs < myString.Length)
{
offs = myString.IndexOf(myCharacter, offs);;
if (offs == -1)
break;
findIndex.Add(offs);
offs++;
}
for (int i = 0; i < findIndex.Count; i++)
{
Console.Write(findIndex[i]);
}
}
Set an initial offset to the start of the string, try to find index of required character if not found exit, otherwise store the location & increment the offset so the next loop starts after the found position. Then keep looping.
As you do not know how many characters will be found, then a list is better than an array to store the results. It can always be converted to an array with .ToArray() afterwards.
Below should serve the purpose :
var str = "Hello";
var replaced = str.Replace('l', '$');
Even though it's easier to use String.Replace, I just want to give you an explanation why you are getting [2,2,2,2,2] array.
Firstly, IndexOf method returns index of character's first occurence, starting from 0.
Secondly, you are using method overload IndexOf(myCharacter, 0) which "says" that character search should be done always from the start of the string.
To circumvent the issue, you should use IndexOf(myCharacter, i, 1) instead to set the search to start from i-th character, not the start of string.
I guess a simple solution would be to split the string into a character array and then do the comparison?
For example something like:
Console.WriteLine("\nWrite a word/sentence: ");
char[] myString = Console.ReadLine().ToCharArray();
Console.Write("Type the character you would like to replace: ");
char myCharacter = Console.ReadLine().ToCharArray()[0];
int[] findIndex = new int[myString.Length];
int indexCount = 0;
for (int i = 0; i < myString.Length; i++)
{
if (myString[i] == myCharacter)
findIndex[indexCount++] = i;
}
for (int i = 0; i < indexCount; i++)
{
Console.Write(findIndex[i]);
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
so I'm working on some small thing and I'm kind of lost. This is what I have so far.
static void izris()
{
Random bombe = new Random();
int[,] polje = new int[7, 7];
string stolpci = " ABCDEFG";
int vrstice=1;
foreach (char c in stolpci)
{
Console.Write(c);
Console.Write(" ");
}
Console.WriteLine();
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 7; j++)
{
polje[i, j] = bombe.Next(0, 2);
}
}
//izris polja
for(int i=0;i<7;i++)
{
Console.Write(vrstice);
vrstice++;
Console.Write(" ");
for (int j = 0; j < 7; j++)
{
Console.Write(polje[i,j]);
Console.Write(" ");
}
Console.WriteLine();
}
}
So what this does is, it prints a field of 7x7 that contains random numbers from 0 to 1. Now 1 means it is a mine, and 0 means it's not a mine. Now if you look, there are characters marking the columns(ABCDEFG) and numbers from 1-7 marking the rows. Now what I want to do is, for example the user would enter a string and the string would be B4. Then the program would check that and see if the field that the user selected is a mine(0) or a bomb(1). If it is a bomb it would also say how many bombs(1's) are nearby. I have no idea how to do this.
I was thinking of transforming the A-F characters into 0,6 numbers so I could index easier, but I don't know.
So I made this to check if the input is correct.
static void vnospolja()
{
string lokacija;
string nekaj = "A";
int nekaj2 = nekaj[0] - 'A';
lokacija = Convert.ToString(Console.ReadLine());
while (lokacija.Length < 2)
{
string pravilnalokacija=lokacija.Substring(0,1);
int pravilnalokacijaint = pravilnalokacija[0];
if(pravilnalokacijaint>65 && pravilnalokacijaint<72)
{
Console.Write("input ok");
}
string drugiznak = lokacija.Substring(1, 1);
int drugiznakint = drugiznak[0];
if(drugiznakint>0 && drugiznakint<8)
{
Console.Write("input ok");
}
}
}
Now I need some ideas on how I would do this, for instance user enters A4, so the input is correct. So how do I actually move accros my 7,7 field and check for A4? I don't understand this, my friend told me something about a second indexer in my multidimensional field but I have no clue.
to just convert the users input into 0 based coordinates you could use this.
static int[] GetInput()
{
string input = Console.ReadLine();
//validate input here..
int x = input[0] - 'A'; //converts char to int
int y = int.Parse(input.Substring(1)) - 1;
return new int[]{ x, y };
}
You could use this method by doing...
var selected = GetInput();
if(polje[selected[0]][selected[1]] == 1)
{
//its a bomb
}
What about using a Dictionary instead of using an Array?
Dictionary<string, bool> p = new Dictionary<string, bool>();
if (p.ContainsKey("a1"))
{
//do something
}
else { } // not a bomb/mine
So you can easily check wether the field is a bomb.
If you want to translate a user input, such as B4 into row and column, here is a simple way you could do it. Since you already have a collection of column names stolpci, you can use string.IndexOf, which will find the position of a character in a string. For example, B is found in place 2 (using 0-based indexing)
01234567
" ABCDEFG"
Since you would want B to map to column number 1, rather than 2 in the minesweeper array, you would need to subtract one.
As far as the number part goes, you can use int.Parse to read the number. Once again, the number is going to be off by one, because row number 4 actually corresponds to row number 3 in the 0-based indexing for the minesweeper array. So your final result might look something like this:
var input = "B4"; // this would come from the user, hard-coding for example
var column = stolpci.IndexOf(entry.Substring(0, 1)); // 2
var row = int.Parse(entry.Substring(1, 1)); // 4
var isBomb = polje[row - 1, col - 1] == 1; // offset by 1 for 0-based indexing
// do something with this
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
So I'm writing a program that inputs a number (binary) then assigns each digit of that input into an array.
static void Main(string[] args)
{
Console.Write("Please enter a binary number: ");
String input = Console.ReadLine();
int inputLength = input.Length;
int nInput = Convert.ToInt32(input);
int[] digits;
digits = new int[inputLength];
int remain = 10;
int divider = 1;
for (int i = 0; i > inputLength; i++)
{
digits[i] = (nInput % remain) / divider;
remain = remain * 10;
divider = divider * 10;
}
Console.WriteLine("Demo number " + digits[0]);
}
However, it seems like all my arrays have a value of 0, whenever I run the code. Why is that?
So if my input is 11010,
digit[0] should be 0.
digit[1] should be 1.
digit[2] should be 0.
digit[3] should be 1.
digit[4] should be 1.
The Loop is not executing since its condition always false; So you are getting its default value, change the condition as i < inputLength;
If you do so and give the input as "123"
The output on the console will be : Demo number 3; And the array Will be
digit[0]=3
digit[1]=2
digit[2]=1
Few suggestions to improve your code:
use int.TryParse(); instead for Convert.ToInt32(); for avoid throwing conversion exceptions. you can see a comparison here
Since the numbers are in an array you can reverse them using Array.Reverse()
That is ..
String input =Console.ReadLine();
int nInput;
int inputLength = input.Length;
if (int.TryParse(input, out nInput))
{
int[] digits = new int[inputLength];
Array.Reverse(digits);
Console.WriteLine("Reversed Number is:{0}",String.Join( "",digits));
}
else { Console.WriteLine("Wrong input"); }
Try this code!
static void Main(string[] args)
{
string input = Console.ReadLine();
int[] vec = new int[input.Length];
int i = 0;
foreach (char ch in input) {
vec[i] = Convert.ToInt32(ch.ToString());
i++;
}
foreach (int numaux in vec) {
Console.WriteLine(numaux);
}
Console.Read();
}
Just iterate over the input string using foreach statement (Will save you from the error that was already pointed out) and convert each char into an int that will be stored inside of the array.
Cheers!
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have this code:
List<string> dirParts = new List<string>();
int index = 0;
for (int i = 0; i < dirName.Length; i++)
{
index = dirName.IndexOf("/");
string dironly = dirName.Substring(index, dirName.Length - index);
dirParts.Add(dironly);
}
dirName for example contains d/1/2/3/4/5
So I need that in the List dirParts in the end I will have in index 0 d, in index 1 d/1, in index 2 d/1/2, in index 3 d/1/2/3, in index 4 d/1/2/3/4, in index 5 d/1/2/3/4/5
So when I look on the List it should look like this:
d
d/1
d/1/2
d/1/2/3
d/1/2/3/4
d/1/2/3/4/5
Possible implementation:
List<string> dirParts = new List<string>();
int index = -1;
while (true) {
index = dirName.IndexOf("/", index + 1);
if (index < 0) {
dirParts.Add(dirName);
break;
}
else
dirParts.Add(dirName.Substring(0, index));
}
Apart from the fact that this kind of path manipulation is best left to the library, lest your code breaks on strange exceptional directory names, your code works as it does because you look everytime for the same "/".
You should search after the last one:
index = dirName.IndexOf("/", index+1);
If you really want to do it that way:
for (int i = 0; i < dirName.Length; i++) {
index = dirName.IndexOf("/", index);
if (index == -1)
i = index = dirName.Length; //last one
dirParts.Add(dirName.Substring(0, index++));
}
If it's a directory, I like to use Path library personally. The only issue would be the use of / over \ in directory name, so you'd have to call .Replace before inserting:
var orig = "d/1/2/3/4/5"; // Original string
List<String> dirParts = new List<String>(new[]{ orig }); // start out with list of original
// Get the directory below this one. (drop off last folder)
String part = Path.GetDirectoryName(orig);
while (!String.IsNullOrEmpty(part))
{
// add it to the first entry in the list
dirParts.Insert(0, part.Replace('\\','/'));
// get the next parent folder.
part = Path.GetDirectoryName(part);
}
/* dirParts = [ "d", "d/1", "d/1/2", ... ] */
However, if you're just looking for the down and dirty LINQ approach:
var orig = "d/1/2/3/4/5";
String[] parts = orig.Split('/');
var dirParts = Enumerable.Range(1, parts.Length)
.Select (e => String.Join("/", parts.Take(e)));
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.