So I am trying to write a Method that will return to me the number of occurrences of a String in Another String. In this case it's finding the number of spaces in a String. It's as if indexOf() is not recognizing the spaces.
Here is my Method:
public int getNumberCardsDealt()
{
int count = 0;
int len2 = dealtCards.length();
int foundIndex = " ".indexOf(dealtCards);
if (foundIndex != -1)
{
count++;
foundIndex = " ".indexOf(dealtCards, foundIndex + len2);
}
return count;
}
Here is my application:
public class TestDeck
{
public static void main(String [] args)
{
Deck deck1 = new Deck();
int cards = 52;
for(int i = 0; i <= cards; i++)
{
Card card1 = deck1.deal();
Card card2 = deck1.deal();
}
System.out.println(deck1.cardsDealtList());
System.out.println(deck1.getNumberCardsDealt());
}
}
Note that I already have a Card Class and the deal method works.
Check the documentation of the indexOf method. You are using it wrong.
You should change the invocation
" ".indexOf(dealtCards);
To
dealtCards.indexOf(" ");
That is, invoking the method on the concerned string and passing to it the character you are looking for, not the other way around.
Moreover, your method would not calculate it correctly anyway, you should change it to something like:
public int getNumberCardsDealt() {
int count = 0;
int foundIndex = -1; // prevent missing the first space if the string starts by a space, as fixed below (in comments) by Andy Turner
while ((foundIndex = dealtCards.indexOf(" ", foundIndex + 1)) != -1) {
count++;
}
return count;
}
#A.DiMatteo's answer gives you the reason why your indexOf doesn't work currently.
Internally, String.indexOf is basically just iterating through the characters. If you're always just looking for a single character, you can trivially do this iteration yourself to do the counting:
int count = 0;
for (int i = 0; i < dealtCards.length(); ++i) {
if (dealtCards.charAt(i) == ' ') {
++count;
}
}
Related
So I made this to print primes between two numbers of my choice; however, it prints out a comma after the last number and I don't know how to take it off.
Example
in: 0 10
out: 2, 3, 5, 7,
I want 2,3,5,7
Scanner s = new Scanner(System.in);
int a = s.nextInt();
int b = s.nextInt();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){System.out.printf("%d,", i);}
}
}
Use a boolean to keep track of whether you've printed anything yet. Then your format string could be something like
anythingPrinted ? ",%d" : "%d"
That is, only include the comma in the format string if there's something printed.
Use a StringBuilder and write to the console at the end of your program.
StringBuilder sb = new StringBuilder();
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){
// If the length of the StringBuilder is 0, no need for a comma
if(sb.length() != 0) {
sb.append(",");
}
sb.append(i);
}
}
System.out.println(sb);
This might seem like overkill, and for many cases it might be, but I have been writing a source code transcoder and I find this situation coming up a lot. Where I need commas in between values, or a prefix value which is only printed once. So I found it handy to create a class which simplifies things.
Again, you wouldn't probably want to use this if you code had one or two print loops in it, but maybe if you had more than a few. Perhaps you would remove in "on first" part if you were never going to use it.
public class FirstPrintOptions {
private PrintStream printStream;
private String onFirst;
private String remaining;
private boolean trip = false;
public FirstPrintOptions(PrintStream printStream, String onFirst, String remaining) {
this.printStream = printStream;
this.onFirst = onFirst;
this.remaining = remaining;
}
public void print() {
if (!trip) {
if (onFirst != null) {
printStream.print(onFirst);
}
trip = true;
} else {
if (remaining != null) {
printStream.print(remaining);
}
}
}
}
Then use it like this..
FirstPrintOptions firstPrintOptions = new FirstPrintOptions(System.out, null, ",");
for (int x=0;x<10;x++) {
firstPrintOptions.print();
System.out.print(x);
}
The results are..
0,1,2,3,4,5,6,7,8,9
I was testing and I came up with this. I was using compilejava.net so scanner doesn't work. I bypassed that part and just set a and b manually. Basically, it builds a string with the numbers and ends in a comma. Then it prints a substring including everything except the last comma.
import java.util.*;
public class HelloWorld {
public static void main(String[] args) {
//Scanner s = new Scanner(System.in);
int a = 2;
int b = 18;
String c = "Output = ";
for (int i = a; i <= b; i++){
int j;
for (j = 2; j<i; j++){
int p = i%j;
if(p==0){break;}
}
if(i == j){c=c+ Integer.toString(i) + ",";}
}
System.out.print(c.subSequence(0, c.length()-1));
}
}
this program for finding factors of a number
for(i=1;i<=number;i++)
{
if(number%i==0)
{
system.out.print(i);
if(i!=0)
{system.out.print(",");}
}
}
so i get the output for 10 as
1,2,5,10
I am learning Java and wonder how I can get two numbers in same line.
Is this algorithm is okay, what can I do improve? What can you suggest me?
import java.util.Scanner;
public class Main{
public static int Separate(String Values, int Order){
String toReturn = "";
int Counter = 0;
for(int Iterator = 0; Iterator < Values.length(); Iterator = Iterator + 1){
if(Values.charAt(Iterator) == ' ') {
if(Order == Counter) break;
else{
toReturn = "";
Counter = Counter + 1;
}
}
else toReturn += Values.charAt(Iterator);
}
return Integer.parseInt(toReturn);
}
public static void main(String[] args){
Scanner Entry = new Scanner(System.in);
System.out.print("Enter two numbers separated by space: ");
String Number = Entry.nextLine();
int Frst = Separate(Number, 0);
int Scnd = Separate(Number, 1);
}
}
what can I do improve? What can you suggest me?
Adopt the Java Naming Conventions:
Method Names are camelCase, starting with a lower case letter
Field and Property Names and Method Argument Names are camelCase, too
Basically only Class and Interface Names start with an upper case letter in Java.
public static int separate(String values, int order){
String toReturn = "";
int counter = 0;
for(int iterator = 0; ...) { ...
Else I'd say: This algorithm is pretty solid for a beginner. It's easy to understand what's going on.
Of course Java provides much more sophisticated tools to solve this, using for example Regular Expressions with myString.split(...), or Streams with IntStream intStream = myString.chars().
Last but not least you could add Exception Handling: What happens if Integer.parseInt is given some non-number? It will crash.
try {
return Integer.parseInt(toReturn);
} catch (NumberFormatException e) {
// when "toReturn" cannot be parsed to an int, return a
// default value instead of crashing your application
return 0;
}
Or if crashing is the desired behavior, or you can ensure that this method is never called with an illegal String, leave it as it is (= don't add try catch)
I think what you've done is great for well-formatted input, where you have a single space character between the numbers. As others have pointer out, following Java naming conventions will greatly improve the readability of your code.
Handling sequences of space characters, possible before, between, and after your numbers is a little tricky. The general pattern would be to consume any sequences of spaces, remember the current position, consume the sequence of digits, then if we're at the correct position return the parsed number.
public static int separate(String str, int order)
{
for(int i = 0, pos = 0; ; pos++)
{
while(i < str.length() && str.charAt(i) == ' ') i += 1;
int j = i;
while(i < str.length() && str.charAt(i) != ' ') i += 1;
if(i == j) throw new IllegalStateException("Missing number!");
if(order == pos)
{
// handle NumberFormatException
return Integer.parseInt(str.substring(j, i));
}
}
}
Test:
String s = " 23432 798 44";
for(int i=0; i<3; i++)
System.out.print(separate(s, i) + " ");
Output:
23432 798 44
As the title says, I'm working on a project in which I'm searching a given text, moby dick in this case, for a key word. However instead of the word being linear, we are trying to find it via a skip distance ( instead of cat, looking for c---a---t).
I've tried multiple ways, yet can't seem to get it to actually finish one skip distance, have it not work, and call the next allowed distance (incrementing by 1 until a preset limit is reached)
The following is the current method in which this search is done, perhaps this is just something silly that I'm missing?
private int[] search()
throws IOException
{
/*
tlength is the text file length,
plength is the length of the
pattern word (cat in the original post),
text[] is a character array of the text file.
*/
int i=0, j;
int match[] = new int[2];
int skipDist = 2;
while(skipDist <= 100)
{
while(i<=tlength-(plength * skipDist))
{
j=plength-1;
while(j>=0 && pattern[j]==text[i+(j * skipDist)])j--;
if (j<0)
{
match[0] = skipDist;
match[1] = i;
return match;
}
else
{
i++;
}
}
skipDist = skipDist + 1;
}
System.out.println("There was no match!");
System.exit(0);
return match;
}
I do not know about the method you posted, but you can use this instead. I've used string and char array for this:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int skipDistance = 2;
for(int i = 0; i< (s.length() - (skipDistance*(check.length-1))); i++)
{
boolean checkValid = true;
for(int j = 0; j<check.length; j++)
{
if(!(s.charAt(i + (j*skipDistance))==check[j]))
{
checkValid = false;
}
}
if(checkValid)
return true;
}
return false;
}
Feed the pattern to match in the char array 'check'.
String "adecrayt" evaluates true. String "cat" evaluates false.
Hope this helps.
[This part was for fixed skip distance]
+++++++++++++++++++++++++++
Now for any skip distance between 2 and 100:
public boolean checkString (String s)
{
char[] check = {'c','a','t'};
int index = 0;
int[] arr = new int[check.length];
for(int i = 0; i< (s.length()); i++)
{
if(check[index]==s.charAt(i))
{
arr[index++] = i;
}
}
boolean flag = true;
if(index==(check.length))
{
for(int i = 0; i<arr.length-1; i++)
{
int skip = arr[i+1]-arr[i];
if(!((skip>2)&&(skip<100)))
{
flag = false;
}
else
{
System.out.println("Skip Distance : "+skip);
}
}
}
else
{
flag = false;
}
return flag;
}
If you pass in a String, you only need one line:
public static String search(String s, int skipDist) {
return s.replaceAll(".*(c.{2," + skipDist + "}a.{2," + skipDist + "}t)?.*", "$1");
}
If no match found, a blank will be returned.
As i have tried ,it gives ArrayIndexOutOfBounds Ecxeption and does not print last char
please help me to find bug in my code.or is there any alternate
public static void sequenceCount(String s) {
int counter;
int i=0;
char c;
char[] arr = s.toCharArray();
while(i<arr.length){
counter=0;
c = arr[i];
while(c==arr[i]){
counter++;
i++;
}
System.out.println("letter"+" "+c+":"+"number of times"+counter);
}
}
As i am a novice to java my code may be inefficient
Your inner loop is not bound by the length of the array. Try:
while(i < arr.length && c==arr[i]){
counter++;
i++;
}
This works - you need to ensure that your inner loop doesn't pass beyond the end of the string, and you need to always catch the last letter, too:
public static void sequenceCount(String s) {
char[] arr = s.toCharArray();
int i = 0, n = arr.length;
while (i < n) {
char c = arr[i];
int count = 0;
do {
++i; ++count;
} while (i < n && arr[i] == c);
System.out.println("letter "+ c +":"+"number of times " + count);
}
}
My approach would be to use two for loops.
The first for loop would run a loop with the decimal equivalent of A to Z.
The second for loop would run a loop that runs through the entire character array/string (I'd prefer a string rather than a char array here) and check to see if that given value at that index is equal the the value ran by the first for loop. If they are equal than add one to count. Print.
Don't forget to reset your counter after every run as well.
Similar Topic can be found here: Counting letters in a string using two for-loops
While many answers here are O(n^2), I tried to do it within O(n) time using recursion. This is modified from existing code that I already had so I know the method returns an int, but I don't use it (it's left over from copied code - fix it as you see fit)
public class CountCharSeqRecursive {
private String test = "AAABBA"; // (3)A(2)B(1)A
private StringBuilder runningString = new StringBuilder();
public static void main(String[] args) {
CountCharSeqRecursive t = new CountCharSeqRecursive();
System.out.println(t.getEncryptedValue(t.test));
}
public String getEncryptedValue(String seq){
int startIndex=0;
this.createCounterSeq(seq.charAt(startIndex), seq, startIndex);
return runningString.toString();
}
private int createCounterSeq(char prev, String sequence, int currentIndex){
return createCounterSeq(prev, sequence, currentIndex, 0);
}
private int createCounterSeq(char prev, String sequence, int currentIndex, int count){
if(currentIndex<sequence.length()){
char current = sequence.charAt(currentIndex);
if((prev^current) < 1){
++count;
}else {
this.addToSequence(count, prev);
count = 1;
}
return count += createCounterSeq(current, sequence, ++currentIndex, count);
}
this.addToSequence(count, prev);
return count;
}
private void addToSequence(int count, char ch){
runningString.append("("+count+")").append(ch);
}
}
My solution using HashSet, Works for all cases of a non-empty string.
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Character> set = new HashSet<Character>();
String input = "aabbcdeaab";
set.add(input.charAt(0));
int count = 1;
StringBuilder output = new StringBuilder("");
for(int i=1;i<input.length();i++) {
char next = input.charAt(i);
if(set.contains(next)) {
count++;
}else {
char prev = input.charAt(i-1);
output.append(Character.toString(prev) + count );
set.remove(prev);
set.add(next);
count=1;
}
}
output.append(Character.toString(input.charAt(input.length()-1)) + count );
System.out.println(output.toString());
}
I'm trying to solve the string similarity question on interviewstreet.com. My code is working for 7/10 cases (and it is exceeding the time limit for the other 3).
Here's my code -
public class Solution {
public static void main(String[] args) {
Scanner user_input = new Scanner(System.in);
String v1 = user_input.next();
int number_cases = Integer.parseInt(v1);
String[] cases = new String[number_cases];
for(int i=0;i<number_cases;i++)
cases[i] = user_input.next();
for(int k=0;k<number_cases;k++){
int similarity = solve(cases[k]);
System.out.println(similarity);
}
}
static int solve(String sample){
int len=sample.length();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(sample.charAt(j-i)==sample.charAt(j))
sim++;
else
break;
}
}
return sim;
}
}
Here's the question -
For two strings A and B, we define the similarity of the strings to be the length of the longest prefix common to both strings. For example, the similarity of strings "abc" and "abd" is 2, while the similarity of strings "aaa" and "aaab" is 3.
Calculate the sum of similarities of a string S with each of it's suffixes.
Input:
The first line contains the number of test cases T. Each of the next T lines contains a string each.
Output:
Output T lines containing the answer for the corresponding test case.
Constraints:
1 <= T <= 10
The length of each string is at most 100000 and contains only lower case characters.
Sample Input:
2
ababaa
aa
Sample Output:
11
3
Explanation:
For the first case, the suffixes of the string are "ababaa", "babaa", "abaa", "baa", "aa" and "a". The similarities of each of these strings with the string "ababaa" are 6,0,3,0,1,1 respectively. Thus the answer is 6 + 0 + 3 + 0 + 1 + 1 = 11.
For the second case, the answer is 2 + 1 = 3.
How can I improve the running speed of the code. It becomes harder since the website does not provide a list of test cases it uses.
I used char[] instead of strings. It reduced the running time from 5.3 seconds to 4.7 seconds and for the test cases and it worked. Here's the code -
static int solve(String sample){
int len=sample.length();
char[] letters = sample.toCharArray();
int sim=0;
for(int i=0;i<len;i++){
for(int j=i;j<len;j++){
if(letters[j-i]==letters[j])
sim++;
else
break;
}
}
return sim;
}
used a different algorithm. run a loop for n times where n is equals to length the main string. for each loop generate all the suffix of the string starting for ith string and match it with the second string. when you find unmatched character break the loop add j's value to counter integer c.
import java.io.BufferedReader;
import java.io.InputStreamReader;
class Solution {
public static void main(String args[]) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(in.readLine());
for (int i = 0; i < T; i++) {
String line = in.readLine();
System.out.println(count(line));
}
}
private static int count(String input) {
int c = 0, j;
char[] array = input.toCharArray();
int n = array.length;
for (int i = 0; i < n; i++) {
for (j = 0; j < n - i && i + j < n; j++)
if (array[i + j] != array[j])
break;
c+=j;
}
return c;
}
}
I spent some time to resolve this question, and here is an example of my code (it works for me, and pass thru all the test-cases):
static long stringSimilarity(String a) {
int len=a.length();
char[] letters = a.toCharArray();
char localChar = letters[0];
long sim=0;
int sameCharsRow = 0;
boolean isFirstTime = true;
for(int i=0;i<len;i++){
if (localChar == letters[i]) {
for(int j = i + sameCharsRow;j<len;j++){
if (isFirstTime && letters[j] == localChar) {
sameCharsRow++;
} else {
isFirstTime = false;
}
if(letters[j-i]==letters[j])
sim++;
else
break;
}
if (sameCharsRow > 0) {
sameCharsRow--;
sim += sameCharsRow;
}
isFirstTime = true;
}
}
return sim;
}
The point is that we need to speed up strings with the same content, and then we will have better performance with test cases 10 and 11.
Initialize sim with the length of the sample string and start the outer loop with 1 because we now in advance that the comparison of the sample string with itself will add its own length value to the result.
import java.util.Scanner;
public class StringSimilarity
{
public static void main(String args[])
{
Scanner user_input = new Scanner(System.in);
int count = Integer.parseInt(user_input.next());
char[] nextLine = user_input.next().toCharArray();
try
{
while(nextLine!= null )
{
int length = nextLine.length;
int suffixCount =length;
for(int i=1;i<length;i++)
{
int j =0;
int k=i;
for(;k<length && nextLine[k++] == nextLine[j++]; suffixCount++);
}
System.out.println(suffixCount);
if(--count < 0)
{
System.exit(0);
}
nextLine = user_input.next().toCharArray();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}