i am currently tried to create a small program were the user enter a string in a text area, clicks on a button and the program counts the frequency of different characters in the string and shows the result on another text area.
E.g. Step 1:- User enter:- aaabbbbbbcccdd
Step 2:- User click the button
Step 3:- a 3
b 6
c 3
d 1
This is what I've done so far....
public partial class Form1 : Form
{
Dictionary<string, int> dic = new Dictionary<string, int>();
string s = "";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
s = textBox1.Text;
int count = 0;
for (int i = 0; i < s.Length; i++ )
{
textBox2.Text = Convert.ToString(s[i]);
if (dic.Equals(s[i]))
{
count++;
}
else
{
dic.Add(Convert.ToString(s[i]), count++);
}
}
}
}
}
Any ideas or help how can I countinue because till now the program is giving a run time error when there are same charachter!!
Thank You
var lettersAndCounts = s.GroupBy(c=>c).Select(group => new {
Letter= group.Key,
Count = group.Count()
});
Instead of dic.Equals use dic.ContainsKey. However, i would use this little linq query:
Dictionary<string, int> dict = textBox1.Text
.GroupBy(c => c)
.ToDictionary(g => g.Key.ToString(), g => g.Count());
You are attempting to compare the entire dictionary to a string, that doesn't tell you if there is a key in the dictionary that corresponds to the string. As the dictionary never is equal to the string, your code will always think that it should add a new item even if one already exists, and that is the cause of the runtime error.
Use the ContainsKey method to check if the string exists as a key in the dictionary.
Instead of using a variable count, you would want to increase the numbers in the dictionary, and initialise new items with a count of one:
string key = s[i].ToString();
textBox2.Text = key;
if (dic.ContainsKey(key)) {
dic[key]++;
} else {
dic.Add(key, 1);
}
I'm going to suggest a different and somewhat simpler approach for doing this. Assuming you are using English strings, you can create an array with capacity = 26. Then depending on the character you encounter you would increment the appropriate index in the array. For example, if the character is 'a' increment count at index 0, if the character is 'b' increment the count at index 1, etc...
Your implementation will look something like this:
int count[] = new int [26] {0};
for(int i = 0; i < s.length; i++)
{
count[Char.ToLower(s[i]) - int('a')]++;
}
When this finishes you will have the number of 'a's in count[0] and the number of 'z's in count[25].
Related
import java.util.Scanner;
class Palindrome_string
{
public static void main()
{
System.out.println("\f");
Scanner sc = new Scanner(System.in);
System.out.println("Enter a string");
String a = sc.nextLine();
int b = a.length();
String rev = "";
for (int i = b - 1; i >= 0; i--)
{
char c = a.charAt(i);
rev = rev + c;
}
System.out.println("Original word "+a);
System.out.println("Reversed word "+rev);
a = a.toLowerCase();
rev = rev.toLowerCase();
if (a == rev)
{
System.out.println("It is a palindrome");
}
else
{
System.out.println("It is not a palindrome");
}
sc.close();
}
}
The program compiles properly. Still, when running the program, the message which tells if it is a palindrome prints incorrectly. What changes do I make? Here is a picture of the output. Even though the word 'level' (which is a palindrome) has been inputted, it shows that it isn't a palindrome. What changes should I make? output pic
You should not use == to compare two strings because it compares the reference of the string, i.e. whether they are the same object or not.
Use .equals() instead. It tests for value equality. So in your case:
if (a.equals(rev))
{
System.out.println("It is a palindrome");
}
Also try not to use single-letter variable names except for index variables when iterating over a list etc. It's bad practice.
I am trying to pass checked items from one listview to another listview in a separate activity. Ideally, the user would click all of the items they wanted, then click a button; then, the button would take all of the items from the rows clicked to the new activity. The problem that I keep having is when I click on the row; all of the information shows up on the next activity instead of the individual rows there were selected.
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
adapterTwo.setCheckBox(position);
adapterTwo.notifyDataSetChanged();
}
});
practiceFinal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String entry = "";
String judge ="";
Integer points = 0;
Integer work = 0;
Integer design = 0;
Integer doc = 0;
Integer pres= 0;
Integer safety= 0;
Integer diff = 0;
String ribbon ="";
Intent intent = new Intent(CSS.this, FinalCSS.class);
for (Team hold: adapterTwo.getTeamArrayList())
{
if (hold.isChecked())
{
}
else
{
entry += " "+ hold.getEntryNumber();
judge += hold.getTeamJudgeNumber();
points+= hold.getTotalPoints();
work+= hold.getWorkmanship();
design += hold.getDesign();
doc += hold.getDocumnetation();
pres+= hold.getPresentation();
safety += hold.getSafety();
diff += hold.getDifficulty();
ribbon += hold.getRibbon();
intent.putExtra( "KeyEntry", entry);
intent.putExtra("KeyJudge", judge);
intent.putExtra("KeyPoints", points);
intent.putExtra("KeyWork", work);
intent.putExtra("KeyDesign", design);
intent.putExtra("KeyDoc",doc);
intent.putExtra("KeyPres", pres);
intent.putExtra("KeySafety", safety);
intent.putExtra("KeyRibbon", ribbon);
intent.putExtra("KeyDiff", diff);
}
}
startActivity(intent);
}
});
listView = findViewById(R.id.listViewFinal);
teamsList= new ArrayList<>();
String entry = getIntent().getStringExtra("KeyEntry");
String judge=getIntent().getStringExtra("KeyJudge");
Integer points= getIntent().getIntExtra("KeyPoints",0);
Integer workmanship=getIntent().getIntExtra("KeyWork",0);
Integer design=getIntent().getIntExtra("KeyDesign",0);
Integer documentation =getIntent().getIntExtra("KeyDoc",0);
Integer pres = getIntent().getIntExtra("KeyPres",0);
Integer difficulty =getIntent().getIntExtra("KeyDiff",0);
Integer safety =getIntent().getIntExtra("KeySafety",0);
String ribbon= getIntent().getStringExtra("KeyRibbon");
Team teams = null;
teams = new Team(judge,entry,points, workmanship,design,documentation,pres,difficulty,safety,ribbon,true);
teamsList.add(teams);
Team teamsT = null;
teamsT = new Team(judge,entry,points, workmanship,design,documentation,pres,difficulty,safety,ribbon,true);
teamsList.add(teamsT);
TeamAdapterTwo adapterTwo = new TeamAdapterTwo(FinalCSS.this, teamsList);
listView.setAdapter(adapterTwo);
Second ActivityFirst ActivitySecond Activity
You are concatenate the information on a global variable. Thus, if we trace the points attribute evolution, we have:
points = 0
points += 1 (points = 1)
points += 2 (points = 3)
points += 3 (points = 6)
points += 4 (points = 10)
Moreover, intent.putExtra erase the old value associated to a key, so at each iteration of the loop, you are replacing the old value of points by the new one. Therefore, at the end, you will give points = 10 to the second Activity.
You have two options:
Create a unique key for each hold but it will not be easy for the second Activity to know this unique key.
Instead of put an integer as extra, put an array of integers (I recommend this way)
However, you seem to have an other issue because the final value of points is the sum of all lines rather than the sum of the checked ones.
As an assignment we are supposed to create methods that copy what string methods do. We are just learning methods and I understand them, but am having trouble getting it to work.
given:
private String st = "";
public void setString(String p){
st = p;
}
public String getString(){
return st;
}
I need to create public int indexOf(char index){}, and public String substring(int start, int end){} I've succesfuly made charAt, and equals but I need some help. We are only allowed to use String methods charAt(), and length(), and + operator. No arrays or anything more advanced either. This is how I'm guessing you start these methods:
public int indexOf(char index){
for(int i = 0; i < st.length(); i++){
return index;
}
return 0;
}
public String substring(int start, int end){
for(int i = 0; i < st.length(); i++){
}
return new String(st + start);
}
thanks!
here's my two working methods:
public boolean equals(String index){
for(int a = 0; a < index.length() && a < st.length(); a++){
if(index.charAt(a) == st.charAt(a) && index.length() == st.length()){
return true;
}
else{
return false;
}
}
return false;
}
public char charAt(int index){
if(index >= 0 && index <= st.length() - 1)
return st.charAt(index);
else
return 0;
}
For your indexOf method, you're on the right track. You'll want to modify the code in the loop. Since you're looping through the whole String, and you only have two methods available, which will help you most to get the characters from the String? Look to your other methods (equals and charAt) to see how you did them, it might give a hint. Remember, you want find a single character in your String and print out the index in which you found it.
For your substring method what you need to do is get all the characters that are represented beginning at start index and go up until end index. A loop is a good start, but you will need a base String to hold your progress in (you will need an empty String). The beginning and end point of your loop need a looking at. For substring, you want to get everything starting at start and everything before end. For instance, if I do the following:
String myString = "Racecar";
String sub = myString.substring(1, 4);
System.out.println(sub);
I should get the output ace.
I would give you the answer, but I think helping guide your reasoning will give you more benefit. Enjoy your assignment!
A string is called a square string if it can be obtained by concatenating two copies of the same string. For example, "abab", "aa" are square strings, while "aaa", "abba" are not. Given a string, how many subsequences of the string are square strings? A subsequence of a string can be obtained by deleting zero or more characters from it, and maintaining the relative order of the remaining characters.The subsequence need not be unique.
eg string 'aaa' will have 3 square subsequences
Observation 1: The length of a square string is always even.
Observation 2: Every square subsequence of length 2n (n>1) is a combination of two shorter subsequences: one of length 2(n-1) and one of length 2.
First, find the subsequences of length two, i.e. the characters that occur twice or more in the string. We'll call these pairs. For each subsequence of length 2 (1 pair), remember the position of the first and last character in the sequence.
Now, suppose we have all subsequences of length 2(n-1), and we know for each where in the string the first and second part begins and ends. We can find sequences of length 2n by using observation 2:
Go through all the subsequences of length 2(n-1), and find all pairs where the first item in the pair lies between the last position of the first part and the first position of the second part, and the second item lies after the last position of the second part. Every time such a pair is found, combine it with the current subsequence of length 2(n-2) into a new subsequence of length 2n.
Repeat the last step until no more new square subsequences are found.
Psuedocode:
total_square_substrings <- 0
# Find every substring
for i in 1:length_of_string {
# Odd strings are not square, continue
if((length_of_string-i) % 2 == 1)
continue;
for j in 1:length_of_string {
# Remove i characters from the string, starting at character j
substring <- substr(string,0,j) + substr(string,j+1,length_of_string);
# Test all ways of splitting the substring into even, whole parts (e.g. if string is of length 15, this splits by 3 and 5)
SubstringTest: for(k in 2:(length_of_substring/2))
{
if(length_of_substring % k > 0)
continue;
first_partition <- substring[1:partition_size];
# Test every partition against the first for equality, if all pass, we have a square substring
for(m in 2:k)
{
if(first_partition != substring[(k-1)*partition_size:k*partition_size])
continue SubstringTest;
}
# We have a square substring, move on to next substring
total_square_substrings++;
break SubstringTest;
}
}
}
Here's a solution using LINQ:
IEnumerable<string> input = new[] {"a","a","a"};
// The next line assumes the existence of a "PowerSet" method for IEnumerable<T>.
// I'll provide my implementation of the method later.
IEnumerable<IEnumerable<string>> powerSet = input.PowerSet();
// Once you have the power set of all subsequences, select only those that are "square".
IEnumerable<IEnumerable<string>> squares = powerSet.Where(x => x.Take(x.Count()/2).SequenceEqual(x.Skip(x.Count()/2)));
Console.WriteLine(squares);
And here is my PowerSet extension method, along with a "Choose" extension method that is required by PowerSet:
public static class CombinatorialExtensionMethods
{
public static IEnumerable<IEnumerable<T>> Choose<T>(this IEnumerable<T> seq, int k)
{
// Use "Select With Index" to create IEnumerable<anonymous type containing sequence values with indexes>
var indexedSeq = seq.Select((Value, Index) => new {Value, Index});
// Create k copies of the sequence to join
var sequences = Enumerable.Repeat(indexedSeq,k);
// Create IEnumerable<TypeOf(indexedSeq)> containing one empty sequence
/// To create an empty sequence of the same anonymous type as indexedSeq, allow the compiler to infer the type from a query expression
var emptySequence =
from item in indexedSeq
where false
select item;
var emptyProduct = Enumerable.Repeat(emptySequence,1);
// Select "Choose" permutations, using Index to order the items
var indexChoose = sequences.Aggregate(
emptyProduct,
(accumulator, sequence) =>
from accseq in accumulator
from item in sequence
where accseq.All(accitem => accitem.Index < item.Index)
select accseq.Concat(new[] { item }));
// Select just the Value from each permutation
IEnumerable<IEnumerable<T>> result =
from item in indexChoose
select item.Select((x) => x.Value);
return result;
}
public static IEnumerable<IEnumerable<T>> PowerSet<T>(this IEnumerable<T> seq)
{
IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() };
for (int i=1; i<=seq.Count(); i++)
{
result = result.Concat(seq.Choose<T>(i));
}
return result;
}
}
I initially derive all possible sub-sequences and then i will check if the derived sub-sequence is a square sub-sequence or not
import java.io.*;
import java.util.*;
public class Subsequence {
static int count;
public static void print(String prefix, String remaining, int k) {
if (k == 0) {
//System.out.println(prefix);
if(prefix.length() %2 == 0 && check(prefix) != 0 && prefix.length() != 0)
{
count++;
//System.out.println(prefix);
}
return;
}
if (remaining.length() == 0)
return;
print(prefix + remaining.charAt(0), remaining.substring(1), k-1);
print(prefix, remaining.substring(1), k);
}
public static void main(String[] args)
{
//String s = "aaa";
Scanner sc = new Scanner(System.in);
int t=Integer.parseInt(sc.nextLine());
while((t--)>0)
{
count = 0;
String s = sc.nextLine();
for(int i=0;i<=s.length();i++)
{
print("",s,i);
}
System.out.println(count);
}
}
public static int check(String s)
{
int i=0,j=(s.length())/2;
for(;i<(s.length())/2 && j < (s.length());i++,j++)
{
if(s.charAt(i)==s.charAt(j))
{
continue;
}
else
return 0;
}
return 1;
}
}
import java.io.*;
import java.util.*;
public class Solution {
/*
Sample Input:
3
aaa
abab
baaba
Sample Output:
3
3
6
*/
public static void main(String[] args) {
//Creating an object of SquareString class
SquareString squareStringObject=new SquareString();
Scanner in = new Scanner(System.in);
//Number of Test Cases
int T = in.nextInt();
in.nextLine();
String[] inputString=new String[T];
for(int i=0;i<T;i++){
// Taking input and storing in String Array
inputString[i]=in.nextLine();
}
for(int i=0;i<T;i++){
//Calculating and printing the number of Square Strings
squareStringObject.numberOfSquareStrings(inputString[i]);
}
}
}
class SquareString{
//The counter maintained for keeping a count of Square Strings
private int squareStringCounter;
//Default Constructor initialising the counter as 0
public SquareString(){
squareStringCounter=0;
}
//Function calculates and prints the number of square strings
public void numberOfSquareStrings(String inputString){
squareStringCounter=0;
//Initialising the string part1 as a single character iterated over the length
for(int iterStr1=0;iterStr1<inputString.length()-1;iterStr1++){
String str1=""+inputString.charAt(iterStr1);
String str2=inputString.substring(iterStr1+1);
//Calling a recursive method to generate substring
generateSubstringAndCountSquareStrings(str1,str2);
}
System.out.println(squareStringCounter);
}
//Recursive method to generate sub strings
private void generateSubstringAndCountSquareStrings(String str1,String str2){
for(int iterStr2=0;iterStr2<str2.length();iterStr2++){
String newStr1=str1+str2.charAt(iterStr2);
if(isSquareString(newStr1)){
squareStringCounter++;
}
String newStr2=str2.substring(iterStr2+1);
generateSubstringAndCountSquareStrings(newStr1,newStr2);
}
}
private boolean isSquareString(String str){
if(str.length()%2!=0)
return false;
String strPart1=str.substring(0,str.length()/2);
String strPart2=str.substring(str.length()/2);
return strPart1.equals(strPart2);
}
}
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 7 years ago.
Improve this question
I saw this in an interview question ,
Given a sorting order string, you are asked to sort the input string based on the given sorting order string.
for example if the sorting order string is dfbcae
and the Input string is abcdeeabc
the output should be dbbccaaee.
any ideas on how to do this , in an efficient way ?
The Counting Sort option is pretty cool, and fast when the string to be sorted is long compared to the sort order string.
create an array where each index corresponds to a letter in the alphabet, this is the count array
for each letter in the sort target, increment the index in the count array which corresponds to that letter
for each letter in the sort order string
add that letter to the end of the output string a number of times equal to it's count in the count array
Algorithmic complexity is O(n) where n is the length of the string to be sorted. As the Wikipedia article explains we're able to beat the lower bound on standard comparison based sorting because this isn't a comparison based sort.
Here's some pseudocode.
char[26] countArray;
foreach(char c in sortTarget)
{
countArray[c - 'a']++;
}
int head = 0;
foreach(char c in sortOrder)
{
while(countArray[c - 'a'] > 0)
{
sortTarget[head] = c;
head++;
countArray[c - 'a']--;
}
}
Note: this implementation requires that both strings contain only lowercase characters.
Here's a nice easy to understand algorithm that has decent algorithmic complexity.
For each character in the sort order string
scan string to be sorted, starting at first non-ordered character (you can keep track of this character with an index or pointer)
when you find an occurrence of the specified character, swap it with the first non-ordered character
increment the index for the first non-ordered character
This is O(n*m), where n is the length of the string to be sorted and m is the length of the sort order string. We're able to beat the lower bound on comparison based sorting because this algorithm doesn't really use comparisons. Like Counting Sort it relies on the fact that you have a predefined finite external ordering set.
Here's some psuedocode:
int head = 0;
foreach(char c in sortOrder)
{
for(int i = head; i < sortTarget.length; i++)
{
if(sortTarget[i] == c)
{
// swap i with head
char temp = sortTarget[head];
sortTarget[head] = sortTarget[i];
sortTarget[i] = temp;
head++;
}
}
}
In Python, you can just create an index and use that in a comparison expression:
order = 'dfbcae'
input = 'abcdeeabc'
index = dict([ (y,x) for (x,y) in enumerate(order) ])
output = sorted(input, cmp=lambda x,y: index[x] - index[y])
print 'input=',''.join(input)
print 'output=',''.join(output)
gives this output:
input= abcdeeabc
output= dbbccaaee
Use binary search to find all the "split points" between different letters, then use the length of each segment directly. This will be asymptotically faster then naive counting sort, but will be harder to implement:
Use an array of size 26*2 to store the begin and end of each letter;
Inspect the middle element, see if it is different from the element left to it. If so, then this is the begin for the middle element and end for the element before it;
Throw away the segment with identical begin and end (if there are any), recursively apply this algorithm.
Since there are at most 25 "split"s, you won't have to do the search for more than 25 segemnts, and for each segment it is O(logn). Since this is constant * O(logn), the algorithm is O(nlogn).
And of course, just use counting sort will be easier to implement:
Use an array of size 26 to record the number of different letters;
Scan the input string;
Output the string in the given sorting order.
This is O(n), n being the length of the string.
Interview questions are generally about thought process and don't usually care too much about language features, but I couldn't resist posting a VB.Net 4.0 version anyway.
"Efficient" can mean two different things. The first is "what's the fastest way to make a computer execute a task" and the second is "what's the fastest that we can get a task done". They might sound the same but the first can mean micro-optimizations like int vs short, running timers to compare execution times and spending a week tweaking every millisecond out of an algorithm. The second definition is about how much human time would it take to create the code that does the task (hopefully in a reasonable amount of time). If code A runs 20 times faster than code B but code B took 1/20th of the time to write, depending on the granularity of the timer (1ms vs 20ms, 1 week vs 20 weeks), each version could be considered "efficient".
Dim input = "abcdeeabc"
Dim sort = "dfbcae"
Dim SortChars = sort.ToList()
Dim output = New String((From c In input.ToList() Select c Order By SortChars.IndexOf(c)).ToArray())
Trace.WriteLine(output)
Here is my solution to the question
import java.util.*;
import java.io.*;
class SortString
{
public static void main(String arg[])throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
// System.out.println("Enter 1st String :");
// System.out.println("Enter 1st String :");
// String s1=br.readLine();
// System.out.println("Enter 2nd String :");
// String s2=br.readLine();
String s1="tracctor";
String s2="car";
String com="";
String uncom="";
for(int i=0;i<s2.length();i++)
{
if(s1.contains(""+s2.charAt(i)))
{
com=com+s2.charAt(i);
}
}
System.out.println("Com :"+com);
for(int i=0;i<s1.length();i++)
if(!com.contains(""+s1.charAt(i)))
uncom=uncom+s1.charAt(i);
System.out.println("Uncom "+uncom);
System.out.println("Combined "+(com+uncom));
HashMap<String,Integer> h1=new HashMap<String,Integer>();
for(int i=0;i<s1.length();i++)
{
String m=""+s1.charAt(i);
if(h1.containsKey(m))
{
int val=(int)h1.get(m);
val=val+1;
h1.put(m,val);
}
else
{
h1.put(m,new Integer(1));
}
}
StringBuilder x=new StringBuilder();
for(int i=0;i<com.length();i++)
{
if(h1.containsKey(""+com.charAt(i)))
{
int count=(int)h1.get(""+com.charAt(i));
while(count!=0)
{x.append(""+com.charAt(i));count--;}
}
}
x.append(uncom);
System.out.println("Sort "+x);
}
}
Here is my version which is O(n) in time. Instead of unordered_map, I could have just used a char array of constant size. i.,e. char char_count[256] (and done ++char_count[ch - 'a'] ) assuming the input strings has all ASCII small characters.
string SortOrder(const string& input, const string& sort_order) {
unordered_map<char, int> char_count;
for (auto ch : input) {
++char_count[ch];
}
string res = "";
for (auto ch : sort_order) {
unordered_map<char, int>::iterator it = char_count.find(ch);
if (it != char_count.end()) {
string s(it->second, it->first);
res += s;
}
}
return res;
}
private static String sort(String target, String reference) {
final Map<Character, Integer> referencesMap = new HashMap<Character, Integer>();
for (int i = 0; i < reference.length(); i++) {
char key = reference.charAt(i);
if (!referencesMap.containsKey(key)) {
referencesMap.put(key, i);
}
}
List<Character> chars = new ArrayList<Character>(target.length());
for (int i = 0; i < target.length(); i++) {
chars.add(target.charAt(i));
}
Collections.sort(chars, new Comparator<Character>() {
#Override
public int compare(Character o1, Character o2) {
return referencesMap.get(o1).compareTo(referencesMap.get(o2));
}
});
StringBuilder sb = new StringBuilder();
for (Character c : chars) {
sb.append(c);
}
return sb.toString();
}
In C# I would just use the IComparer Interface and leave it to Array.Sort
void Main()
{
// we defin the IComparer class to define Sort Order
var sortOrder = new SortOrder("dfbcae");
var testOrder = "abcdeeabc".ToCharArray();
// sort the array using Array.Sort
Array.Sort(testOrder, sortOrder);
Console.WriteLine(testOrder.ToString());
}
public class SortOrder : IComparer
{
string sortOrder;
public SortOrder(string sortOrder)
{
this.sortOrder = sortOrder;
}
public int Compare(object obj1, object obj2)
{
var obj1Index = sortOrder.IndexOf((char)obj1);
var obj2Index = sortOrder.IndexOf((char)obj2);
if(obj1Index == -1 || obj2Index == -1)
{
throw new Exception("character not found");
}
if(obj1Index > obj2Index)
{
return 1;
}
else if (obj1Index == obj2Index)
{
return 0;
}
else
{
return -1;
}
}
}