Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
public class Word
{
private string _inputWord;
public Word()
{
Console.WriteLine("Enter a word");
_inputWord = Console.ReadLine();
}
public void sortandcount()
{
char[] test = _inputWord.ToCharArray();
char temp;
int count = 0, tcount = 0;
Array.Sort(test);
int length = test.Length;
temp = test[0];
while (length > 0)
{
for (int i = 0; i < test.Length; i++)
{
if (temp == test[i])
{
count++;
}
}
Console.WriteLine(temp + " " + count);
tcount = tcount + count;
temp = test[tcount]; //this line
length = length - count;
count = 0;
}
}
}
class Program
{
public static void Main() //this line
{
Word obj = new Word();
obj.sortandcount();
}
}
i get exception at two lines i have indicated as a comment(as // this line in the program) on that line,, can u people help me to clear abt this. M idea abt the program is to count the number of characters(same) in a given word.
Eg Apple
a-1
p-2
l-1
e-1
When you've counted all letters then tcount == test.length which means that test[tcount]will index one element to0 far.
Given any array arr then arr[arr.length] will always be out of bounds because the arr is zero indexed. Before temp = test[tcount] you need to ensure that tcount < test.length however you also have an error in your logic
try with the word obo it will print o 2 o 2
a simple implementation of counting the charaters in a word (if the order does not have to be as they appear in the word) would be
var result = test.Aggregate(new Dictionary<char,int>(), (state,c)=>{
if(!state.ContainsKey(c)) { state.Add(c,0); }
state[c] += 1;
return state;
});
foreach(var pair in result) { Console.WriteLine(pair.Key + " " + key.Value); }
EDIT if you need them to be sorted in the same order as they appear in the word then change the foreach to this
foreach(var pair in result.OrderBy(p=>test.IndexOf(p.Key))) {
Console.WriteLine(pair.Key + " " + key.Value);
}
If you want to output the count of letters in a word, try this code:
var testString = "APPLE";
testString.ToCharArray()
.OrderBy(i => i).ToLookup(i => i)
.Select(i => new { letter = i.Key, count = i.Count() }).ToList()
.ForEach(i => Console.WriteLine("letter {0}, count {1}", i.letter, i.count));
This is a bit cleaner and less error prone.
The code contains a bug
int length = test.Length; // This is not zero based
and count is zero based, your loop will do one additional iteration causing
temp = test[tcount]
to fail because tcount now became bigger than the length of test by 1 character.
The best thing to do is
int length = test.Length -1;
Please let me know if this helps :) have a nice day
A little bit more "programmatic" version:
public class Word
{
private string _inputWord;
public Word()
{
Console.WriteLine("Enter a word");
_inputWord = Console.ReadLine();
}
public void SortAndCount()
{
// sort
char[] array = _inputWord.ToCharArray();
Array.Sort(array);
// for all characters
for(int i = 0; i < array.Length; i++)
{
// duplicate check
if(i > 0 && array[i] == array[i - 1])
continue;
// count
int count = 0;
for(int j = 0; j < array.Length; j++)
if(array[i] == array[j])
count++;
Console.WriteLine(array[i] + " " + count);
}
}
}
class Program
{
public static void Main()
{
Word obj = new Word();
obj.SortAndCount();
}
}
Related
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 3 years ago.
Improve this question
I have problem with solution in this example.
Input:>6
Output:0+1+2+3+4+5+6 = 21
Input:> -15
Output:-15<0
Input:>0
Output:0=0
public static string ShowSequence(int n)
{
int sumInt = 0;
string sum = "";
for (int i = 0; i <= n; i++)
{
if (n == 0)
{
sum += i + "=";
}
else if (n < 0)
{
sum += n + "<";
}
else
if (i == n)
{
sum += i + " = ";
}
else
sum += i + "+";
sumInt += i;
}
sum += sumInt;
return sum;
}
Everything works except a negative number , because my program return 0 not -15<0. Thanks for help !
You check your input in the loop, and that's where it goes wrong.
I modified your code, and pulled the check out of the for-loop, and returned early to avoid confusion.
https://dotnetfiddle.net/gLmo62
public static string ShowSequence(int n)
{
if (n == 0)
{
return n + "=";
}
if (n < 0)
{
return n + "<";
}
int sumInt = 0;
string sum = "";
for (int i = 0; i <= n; i++)
{
if (i == n)
{
sum += i + " = ";
}
else
{
sum += i + "+";
}
sumInt += i;
}
sum += sumInt;
return sum;
}
Your Loop Condition i <= n; fails before the start of first iteration when the number is negative. For this reason, the execution never reaches the if/else conditions.
You could rewrite the method with condition checks prior to entering the loop.
public static string ShowSequence(int n)
{
if (n == 0)
{
return n + "=";
}
if (n < 0)
{
return n + "<";
}
int sumInt = 0;
StringBuilder sum = new StringBuilder();
for (int i = 0; i <= n; i++)
{
sum.Append($"{i}{(i==n?" = ":"+")}");
sumInt += i;
}
sum.Append(sumInt);
return sum.ToString();
}
Please note I have also used StringBuilder, instead of strings. The string class is immutable, which means that each time you append/modify a string, you are essentially creating a new string object in memory. In situation like the case in hand, where the string is repeatedly modified, you should avoid the overhead of creating string for every modification. For this purpose, you could use the StringBuilder class.
As an additional note, you could further reduce the code by making use of Linq. For example,
public static string ShowSequence(int n)
{
if (n == 0)
{
return n + "=";
}
if (n < 0)
{
return n + "<";
}
var strBuilder = new StringBuilder();
strBuilder.Append(Enumerable.Range(0, n+1)
.Select(x => x.ToString())
.Aggregate((a, b) => a + "+" + b));
strBuilder.Append($" = {(n*(n+1))/2}");
return strBuilder.ToString();
}
You can simply state the special case: n == 0, `n < 0.
Then use Enumerable.Range to generate all number from 0 to n.
And String.Join, without the "Is that the last elements? Do I need one more + ?".
And Enumerable.Sum to compute the sum.
You will end up with a really straight forward code.
public static string ShowSequence(int n)
{
if (n == 0)
{
return n + " = 0";
}
if (n < 0)
{
return n + " < 0";
}
// generate all numbers from 0 to n. Takes n+1 steps.
var enumeration = Enumerable.Range(0, n+1);
var plusOperatorConcatenation = String.Join(" + ", enumeration ) ;
return plusOperatorConcatenation + " = " + enumeration.Sum();
}
Live Demo: https://dotnetfiddle.net/Iu0vyf
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;
}
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");
}
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 5 years ago.
Improve this question
Have trouble adding a summary for columns number, square and cube for totals. Any pointers where I should be looking at? Below is copy of my code.
static void Main(string[] args)
{
int number;
int total = 0;
Console.WriteLine("number\t" + "square\t" + "cube");
Console.WriteLine("-----------------------------");
for (int i = 0; i <= 20; i += 2)
{
number = i;
int k = 0;
do
{
Console.Write(number + "\t");
number *= i;
total += number;
k++;
} while (k < 3);
Console.WriteLine("Total is",total);
Console.WriteLine();
}
Console.WriteLine("---------------------------------------");
If I understand what you want correctly, one way to do this is to keep track of the running totals for each power (1, 2, and 3) in an array, and then display those values at the end.
The array would have 3 indexes, and each time we increase the 'power' that we're raising our number to, we add that value to the corresponding index in the array.
For example:
static void Main(string[] args)
{
// This array will hold three items:
// - totals[0] = numberTotal
// - totals[1] = squareTotal
// - totals[2] = cubeTotal
var totals = new int[3];
Console.WriteLine("number\t" + "square\t" + "cube");
Console.WriteLine("-----------------------------");
for (int number = 0; number <= 20; number += 2)
{
// Grab a copy of 'number' so we don't modify the loop variable
var thisNumber = number;
for(int powerIndex = 0; powerIndex < 3; powerIndex++)
{
// Write this number to screen
Console.Write($"{0:n0}\t", thisNumber);
// Add this number to the current number in 'power' index
totals[powerIndex] += thisNumber;
// Power up
thisNumber *= number;
}
Console.WriteLine();
}
Console.WriteLine("-----------------------------");
Console.WriteLine("{0:n0}\t{1:n0}\t{2:n0}\t", totals[0], totals[1], totals[2]);
// Alternatively, if you're using C#6.0, you could write:
Console.WriteLine($"{totals[0]:n0}\t{totals[1]:n0}\t{totals[2]:n0}\t");
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
}
Output:
There are two errors in your code:
First one is about Console.WriteLine. To get it working you should pass parameters as for example shown here (it's not the only way to do it but it's the simplest)
Console.WriteLine("Total is" + total);
Secon one is more about algorithm. Let's check when you are adding number to total. If you look closer you can see that you are not adding same number, which you displayed, but your adding number * i ! Thats big mistake but to fix it just swap that two lines like that:
Console.Write(number + "\t");
total += number;
number *= i;
k++;
I belive that fixes every issue, hope it helps :-)
Full code:
using System;
namespace Sum
{
public class Program
{
public static void Main(string[] args)
{
int number;
Console.WriteLine("number\t" + "square\t" + "cube");
Console.WriteLine("-----------------------------");
for (int i = 0; i <= 20; i += 2)
{
number = i;
int total = 0;
int k = 0;
do
{
Console.Write(number + "\t");
total += number;
number *= i;
k++;
} while (k < 3);
Console.WriteLine("Total is "+total);
Console.WriteLine();
}
Console.WriteLine("---------------------------------------");
}
}
}
Instead of looping through each character to see if it's the one you want then adding the index your on to a list like so:
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
{
if (myStr[i] == 'a')
foundIndexes.Add(i);
}
You can use String.IndexOf, see example below:
string s = "abcabcabcabcabc";
var foundIndexes = new List<int>();
long t1 = DateTime.Now.Ticks;
for (int i = s.IndexOf('a'); i > -1; i = s.IndexOf('a', i + 1))
{
// for loop end when i=-1 ('a' not found)
foundIndexes.Add(i);
}
long t2 = DateTime.Now.Ticks - t1; // read this value to see the run time
I use the following extension method to yield all results:
public static IEnumerable<int> AllIndexesOf(this string str, string searchstring)
{
int minIndex = str.IndexOf(searchstring);
while (minIndex != -1)
{
yield return minIndex;
minIndex = str.IndexOf(searchstring, minIndex + searchstring.Length);
}
}
usage:
IEnumerable<int> result = "foobar".AllIndexesOf("o"); // [1,2]
Side note to a edge case: This is a string approach which works for one or more characters. In case of "fooo".AllIndexesOf("oo") the result is just 1 https://dotnetfiddle.net/CPC7D2
How about
string xx = "The quick brown fox jumps over the lazy dog";
char search = 'f';
var result = xx.Select((b, i) => b.Equals(search) ? i : -1).Where(i => i != -1);
The raw iteration is always better & most optimized.
Unless it's a bit complex task, you never really need to seek for a better optimized solution...
So I would suggest to continue with :
var foundIndexes = new List<int>();
for (int i = 0; i < myStr.Length; i++)
if (myStr[i] == 'a') foundIndexes.Add(i);
If the string is short, it may be more efficient to search the string once and count up the number of times the character appears, then allocate an array of that size and search the string a second time, recording the indexes in the array. This will skip any list re-allocations.
What it comes down to is how long the string is and how many times the character appears. If the string is long and the character appears few times, searching it once and appending indicies to a List<int> will be faster. If the character appears many times, then searching the string twice (once to count, and once to fill an array) may be faster. Exactly where the tipping point is depends on many factors that can't be deduced from your question.
If you need to search the string for multiple different characters and get a list of indexes for those characters separately, it may be faster to search through the string once and build a Dictionary<char, List<int>> (or a List<List<int>> using character offsets from \0 as the indicies into the outer array).
Ultimately, you should benchmark your application to find bottlenecks. Often the code that we think will perform slowly is actually very fast, and we spend most of our time blocking on I/O or user input.
public static List<int> GetSubstringLocations(string text, string searchsequence)
{
try
{
List<int> foundIndexes = new List<int> { };
int i = 0;
while (i < text.Length)
{
int cindex = text.IndexOf(searchsequence, i);
if (cindex >= 0)
{
foundIndexes.Add(cindex);
i = cindex;
}
i++;
}
return foundIndexes;
}
catch (Exception ex) { }
return new List<int> { };
}
public static String[] Split(this string s,char c = '\t')
{
if (s == null) return null;
var a = new List<int>();
int i = s.IndexOf(c);
if (i < 0) return new string[] { s };
a.Add(i);
for (i = i+1; i < s.Length; i++) if (s[i] == c) a.Add(i);
var result = new string[a.Count +1];
int startIndex = 0;
result[0] = s.Remove(a[0]);
for(i=0;i<a.Count-1;i++)
{
result[i + 1] = s.Substring(a[i] + 1, a[i + 1] - a[i] - 1);
}
result[a.Count] = s.Substring(a[a.Count - 1] + 1);
return result;
}