This is my method to count the number of parentheses in a string.
public int checkParenthesis(String print, char par){
int num = 0;
for(int i = 0; i<print.length(); i++){
if(print.indexOf(i) == par){
num++;
}
}
return num;
}
It doesn't work. It returns 0.
print is a random string and par is a parenthesis.
You need to use .charAt to get the current character and compare it with par:
if(print.charAt(i) == par)
Another way to do this:
for(char c : print.toCharArray()) {
if(c == par) {
num++;
}
}
You meant charAt instead of indexOf.
The difference is that charAt takes a position in the string (0, 1, ...) and returns the character at that position. indexOf takes a character, and searches the string for the first position where that character is found. You're passing an int to indexOf, not a char, but the compiler accepts this "thanks" to implicit conversions.
In java indexOf is used for checking ch at index. Instead of indexOf u can use string.charAt(index) to get desired result.
public int checkParenthesis(String print, char par){
int num = 0;
for(int i = 0; i<print.length(); i++){
if(print.charAt(i) == par){
num++;
}
}
return num;
}
As others have pointed out, your current algorithm is examining characters at each index with a loop. That would be appropriate with String.charAt(int) but not String.indexOf(int). However, you could certainly implement it with String.indexOf(int, int). Also, I prefer to check for null and an empty input preemptively. Finally, your method counts matching characters (not "checking parenthesis") and doesn't depend on class state so I would make it static. Something like,
public static int countChar(String print, char par) {
if (print == null || print.isEmpty()) {
return 0;
}
int num = 0;
int pos = -1;
while ((pos = print.indexOf(par, pos + 1)) != -1) {
num++;
}
return num;
}
Since Java 9 you can use String#codePoints method:
static long characterCount(String str, char ch) {
// filter the desired characters and return their quantity
return str.codePoints().filter(cp -> cp == ch).count();
}
public static void main(String[] args) {
System.out.println(characterCount("srting))", ')')); // 2
System.out.println(characterCount("{srting}", '{')); // 1
System.out.println(characterCount("(srting)", 's')); // 1
System.out.println(characterCount("[srting]", 'ё')); // 0
}
See also: Recursive method that returns true if the integer exists only once in an array
Just one another way, but with creating extra String objects:
int cnt=print.length()-print.replaceAll(String.valueOf(c),"").length();
Related
I've been trying to create an algorithm where each letter adds points. I don't want to use charAt, I'd like to use the substring method.
My problem is that String letter does not seem to get each letter and the result is always 0.
Is there a way to get each letter and convert it to points?
public class WDLPoints{
public static void main(String[] args){
String word = "LDWWL";
System.out.println(getMatchPoints(word));
}
public static int getMatchPoints(String word) {
int points = 0;
String letter = word.substring(5);
for (int i = 0; i < word.length(); i++) {
if (letter.equals("W")) {
points+=3;
}
else if (letter.equals("D")) {
points+=1;
}
else {
points = 0;
}
}
return points;
}
}
You may try the following changes in your public static int getMatchPoints(String word) method:
for (int i = 0; i < word.length(); i++) {
String letter = word.substring(i, i + 1);
if (letter.equals("W")) {
points+=3;
}
else if (letter.equals("D")) {
points+=1;
}
}
word.substring(i, i + 1) will get a single letter word and will help you compute your score the way you want.
If you want to make it really simple you can just use String.toCharArray() and then iterate over the array of char and check its value:
public static int getMatchPoints(String word) {
int points = 0;
char[] arr = word.toCharArray();
for (char letter : arr) {
if (letter == 'W') {
points += 3;
}
else if (letter == 'D') {
points += 1;
}
}
return points;
}
I also removed your else statement because that was just setting the value to 0 if there is any other letter in the loop. I think you intended it to be points += 0 which does nothing, so it can just be removed.
Example Run:
Input:
String word = "LDWWL";
Output:
7
Note: I am aware you might not be allowed to use this solution, but I thought it would be good info on the possibilities since it does not technically use charAt()
Also I'd like to point out you misunderstand what substring(5) does. This will return all characters after the position of 5 as a single String, it does not separate the String into different characters or anything.
You will find that your variable letter is always the empty String. Here's a better way of doing things:
class WDLPoints
{
public static void main(String[] args)
{
String word = "LDWWL";
System.out.println(getMatchPoints(word));
}
// We have only one method to encode character values, all in one place
public static int getValueForChar(int c)
{
switch((char)c)
{
case 'W': return 3;
case 'D': return 1;
default: return 0; //all non-'W's and non-'D's are worth nothing
}
}
public static int getMatchPoints(String word)
{
// for all the characters in the word
return word.chars()
// get their integer values
.map(WDLPoints::getValueForChar)
// and sum all the values
.sum();
}
}
Assuming your string represents a football teams performance of the last 5 games, you could keep it simple and readable with something like:
public static int getMatchPoints(String word) {
String converted = word.replace('W', '3').replace('D', '1').replace('L', '0');
return converted.chars().map(Character::getNumericValue).sum();
}
This converts your example input "LDWWL" to "01330" and sums each char by getting its numeric value.
I'm doing this problem as practice for using methods outside of the main method. The problem needed us to make three different methods, each of which does a different task, but none of them have to relate with each other.
smallestNumber(): take 3 numbers inputted by the user and output the smallest number
average(): take 3 numbers inputted by the user and output the average
countVowels(): take a phrase inputted by the user and output the number of vowels in that phrase
For me, I am able to return a value from method 1 and method 2 back to the main method.
For method 3, when I try to return the counter value, it ALWAYS returns 0 even if there ARE vowels in the phrase.
Can someone please explain what I am doing wrong? (sorry with indenting issues, I've never used Stack Overflow before)
I don't know why it keeps returning 0
public static int countVowels(String words) {
int count=0;
for (int i=0; i<words.length(); i++) {
if (words.charAt(i) == 'a' || words.charAt(i) == 'e' || words.charAt(i) == 'i' || words.charAt(i) == 'o' || words.charAt(i) == 'u') {
count++;
}
}
return(count);
}
Your count is an int (not a String) so you should return an int. Instead of String.indexOf(String) you should be using String.charAt(int) (or use a for-each loop on String.toCharArray()). There's no need to increment by zero, and you only consider lower case letters (so call String.toLowerCase()). Like,
public static int method3(String words) {
int count = 0;
for (char ch : words.toLowerCase().toCharArray()) {
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
count++;
}
}
return count;
}
Also, consider a more meaningful method name (like countVowels()).
If your method has a return type of String, then return a string:
public static String method3(String words){
int count = 0;
//logic here
return "" + count; // The "" + will convert the count to a string, if that is what you want.
}
You can also change the return type of the method, to return an int:
public static int method3(String words){
int count = 0;
//logic here
return count;
}
Based on your logic, if a string in the variable words has any of the vowels, then it will increment the count by one, if not, it will not increment it and return 0.
If you are sending an empty string or a string with no vowels, the method will return 0.
Move the return outside of loop (your code returning inside, explains why you always get 0)
toLowerCase each word Character, to account for case
Make a Set of all vowels, and check if it contains each character of word (see next bullet)
*Note that indexOf, which your code calls, will always return just the first occurrence's index; that will cause your code to not always return the correct answer, even after moving the return outside the loop. Your code using indexOf also causes it to have a quadratic O(n^2) runtime (where n is the length of word). My solutions here do not use indexOf, and are linear O(n) in runtime. Both your solution and mine are constant O(1) memory space.
As below:
public static String countVowels(String word){
int count = 0;
Set<Character> vowels
= new HashSet<>(Arrays.asList("a", "e", "i", "o", "u"));
for(int i = 0; i < words.length(); i++){
if(vowels.contains(Character.toLowerCase(word.charAt(i)))) {
count++;
}
}
return "This is the number of vowels " + count;
}
Even Better (code style optimization) - use an enhanced-for-loop:
public static String countVowels(String word){
int count = 0;
Set<Character> vowels
= new HashSet<>(Arrays.asList("a", "e", "i", "o", "u"));
for(char curChar: word.toCharArray()){
if(vowels.contains(Character.toLowerCase(curChar))) {
count++;
}
}
return "This is the number of vowels " + count;
}
So... I understand the idea of one main method and then being able to call multiple classes. That we can refer to one directly in order to run different scenarios. AKA use it if it is needed. Static is for one instance while main is overarching
Questions:
1. Where i have placed the bar there is a return; which is used to get me out of this instance. However, it is telling me i need a String. Which makes sense because the method and the output must match?
I have attempted:
1.to return solely the int value
2.to convert the int to string using-String.valueOf(special);
Where is the error?
import java.util.Scanner;
public class Overall{
public static void main(String[] argc){
Scanner input = new Scanner(System.in);
int i = 0;
int containsLowerCase = 0;
System.out.println(" Please give me a string that has a combination of lower, upper, digits and special characters");
String s1 = input.next();
System.out.println(s1);
}
public static String isSpecial (String input){
int special = 0;
int i =0;
for(i=0;i< input.length(); i++){
char c = input.charAt(i);
if (c=='#' || c=='$' || c== '*' || c== '&')
special++;
String.valueOf(special);
}
return special;
_________________________________________________________
^ ONLY FOCUSING ON UPPER HALF ISSUES ^
public static String print (String input){
System.out.println(s1);
}
public static int isDigit (int input){
int digit = 0;
for(i=0;i< input.length(); i++){
char c = imput.charAt(i);
if (character.isDigit(s1.charAt(i))){
isDigit++;
}
return isDigit++;
}
}
public static int isLower (int input){
int digit = 0;
for(i=0;i< input.length(); i++){
char c = imput.carAt(i);
if (character.isLowerCase(s1.charAt(i))){
isLower++;
}
}
}
public static int isUpper (int input){
int digit = 0;
for(i=0;i< input.length(); i++){
char c = imput.carAt(i);
if (character.isUpperCase(s1.charAt(i))){
isUpper++;
}
}
}
}
You return special which is an int, you need to define a new String variable and return that or simply return String.valueOf(special);.
You called the String.valueOf(int) which will convert an int to a String but you need to place the return value of that method in a String variable.
Example: String newStringVariable = String.valueOf(special);
Return String.valueOf(number)
public static String isSpecial (String input){
int special = 0;
int i =0;
for(i=0;i< input.length(); i++){
char c = input.charAt(i);
if (c=='#' || c=='$' || c== '*' || c== '&')
special++;
}
return String.valueOf(special);
I will try to mention all your mistakes, and tell you why it is wrong and what it has ro be like.
First, lets begin with your isSpecial method:
You count the number of times a special character is in your String. Most of its code is right, but I think you wanted return type of int not of String. See, the type you write before the name of the method, in this case String, is what type of Object the method will return. In your method you count the number of times a certain event happens, so you want to return that number to later calculate with that or something else.
The return statement has to be in the method body, and when it is reached, the current method takes that value and gives it back to the call of it. Afterwards the method exits, so after a return this method ended and the program continues where you called that method. Take following code:
public class Test {
public static void main (String [] args){
String testText = "This was written on 2.03.2017";
int numbers = countNumeric (testText);
System.out.println ("The text containes "+ numbers +" numbers");
}
public static int countNumeric (String text){
int count = 0;
for (int i = 0; i < text.length; i++){
if (Character.isDigit (text.charAt (i))
count++;
}
return count;
}
When executing this method, java creates a new String, then passes that String to the countNumeric method, where count is incremented by one for each digit character in the String. Then countNumeric returns the count. The program jumps back to the main method and there takes the return value of countNumeric and puts it into the variable numbers, then it prints that.
Also you seem to have a problem using String.valueOf. String.valueOf is a method, which takes a number and converts it to a string. But since you declared special as int, you cannot store a String in it (and maybe want to use it later on). So to convert a number to a String, you have to create a new variable of type String, like in this simple example:
int number = 123;
String text = String.valueOf (number);
//do something with text
So most of your errors are due to missing returns or wrong return type. Also the reurn in your isDigit method is in the for loop, so it will only look at the first character of the String.
I hope I could help you, and would suggest you to look for a good java step by step tutorial, since you don't seem very familiar with programming.
So I'm creating a program that will output the first character of a string and then the first character of another string. Then the second character of the first string and the second character of the second string, and so on.
I created what is below, I was just wondering if there is an alternative to this using a loop or something rather than substring
public class Whatever
{
public static void main(String[] args)
{
System.out.println (interleave ("abcdefg", "1234"));
}
public static String interleave(String you, String me)
{
if (you.length() == 0) return me;
else if (me.length() == 0) return you;
return you.substring(0,1) + interleave(me, you.substring(1));
}
}
OUTPUT: a1b2c3d4efg
Well, if you really don't want to use substrings, you can use String's toCharArray() method, then you can use a StringBuilder to append the chars. With this you can loop through each of the array's indices.
Doing so, this would be the outcome:
public static String interleave(String you, String me) {
char[] a = you.toCharArray();
char[] b = me.toCharArray();
StringBuilder out = new StringBuilder();
int maxLength = Math.max(a.length, b.length);
for( int i = 0; i < maxLength; i++ ) {
if( i < a.length ) out.append(a[i]);
if( i < b.length ) out.append(b[i]);
}
return out.toString();
}
Your code is efficient enough as it is, though. This can be an alternative, if you really want to avoid substrings.
This is a loop implementation (not handling null value, just to show the logic):
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
for (int i = 0 ; i < Math.max(you.length(), me.length()) ; i++) {
if (i < you.length()) {
result.append(you.charAt(i)); }
if (i < me.length()) {
result.append(me.charAt(i));
}
}
return result.toString();
}
The solution I am proposing is based on the expected output - In your particular case consider using split method of String since you are interleaving by on character.
So do something like this,
String[] xs = "abcdefg".split("");
String[] ys = "1234".split("");
Now loop over the larger array and ensure interleave ensuring that you perform length checks on the smaller one before accessing.
To implement this as a loop you would have to maintain the position in and keep adding until one finishes then tack the rest on. Any larger sized strings should use a StringBuilder. Something like this (untested):
int i = 0;
String result = "";
while(i <= you.length() && i <= me.length())
{
result += you.charAt(i) + me.charAt(i);
i++;
}
if(i == you.length())
result += me.substring(i);
else
result += you.substring(i);
Improved (in some sense) #BenjaminBoutier answer.
StringBuilder is the most efficient way to concatenate Strings.
public static String interleave(String you, String me) {
StringBuilder result = new StringBuilder();
int min = Math.min(you.length(), me.length());
String longest = you.length() > me.length() ? you : me;
int i = 0;
while (i < min) { // mix characters
result.append(you.charAt(i));
result.append(me.charAt(i));
i++;
}
while (i < longest.length()) { // add the leading characters of longest
result.append(longest.charAt(i));
i++;
}
return result.toString();
}
I want to count number of words in my string using recursive method (java)
so far i wrote this code
public static int CountWords(String sen) {
int count = 0;
int i = sen.indexOf(" ");
if (sen.isEmpty()) {
return 0;
}else
if (i == sen.indexOf(" ")) {
return count++;
}
//sen.substring(0,sen.indexOf(" ")-1);
count++;
return count + CountWords(sen.substring(i + 1));
}
i always get 0 when i call the method
can anyone help me make this code run
How you're using indexOf is the problem. You're setting i to the result of calling indexOf, then seeing if it's equal to the result of calling indexOf on the same string with the same parameter. The result of the test i == sen.indexOf(" ") will always be true. That's why you always get 0.
String#indexOf returns -1 if the char it's looking for is not found. indexOf comes in very handy here.
Also you shouldn't need a local count variable. Introducing a variable here just makes the code harder to read, because the reader has to hunt around to figure out what the value of it is.
Assuming your input always has exactly one blank between words this could be done as:
public static int countWords(String s) {
if (s.isEmpty()) return 0;
if (s.indexOf(" ") == -1) return 1;
return 1 + countWords(s.substring(s.indexOf(" ") + 1));
}
For multiple blanks between words you can check for a blank and skip past it:
public static int countWords(String s) {
if (s.isEmpty()) return 0;
if (s.indexOf(' ') == -1) return 1;
if (s.charAt(0) == ' ') return countWords(s.substring(1));
return 1 + countWords(s.substring(s.indexOf(' ') + 1));
}
This should work, I think:
public static int countWords(String sen) {
int i = sen.indexOf(" ");
if (sen.isEmpty()) {
return 0;
} else if (i == -1) {
return 1;
} else return 1 + countWords(sen.substring(i + 1));
}
Some notes on what is happening:
Java naming conventions dictate you should start method names with a lower case letter
The line if (i == sen.indexOf(" ")) is redunant - you just assigned i to be that before, so it'll always evaluate to true.
And therefore, your recursion never gets called. You need to change it so that if sen isn't empty and contains at least one more space, countWords calls itself with sen minus the first word.
This method uses a String with no spaces as a base case. Then it removes everything up to and including the first space in the String and recurses.
It handles both the special case of an empty String and the case that a String passed to the method starts with a space appropriately.
public static int CountWords(String sen)
{ int i = sen.indexOf(" ");
if(sen.isEmpty()) return 0; // special case
if(i == -1) return 1; // base case
if(i != 0)
return 1 + CountWords(sen.substring(i+1));
else
return CountWords(sen.substring(1));
}
This will work -
public static int CountWords(String sen) {
if("".equals(sen)){
return 0;
}
int count = 0;
int i = sen.indexOf(" ");
String substr = sen.substring(0,i+1) ;
if (i != -1) {
count++;
}else{
if(sen.length()>0){
count++;
}
sen="";
}
//sen.substring(0,sen.indexOf(" ")-1);
return count + CountWords(sen.substring(substr.length()));
}