2

This is what I am trying to do:

enter image description here

CountVowel.java

package lab2;


/**
 *
 * @author Shyam
 */

public class CountVowel implements Runnable {
    String[] input;
    int vowels = 0;
    char ch;

    public CountVowel(String[] args) {
        input=args;
    }

    public void run() {
        try {
        for (int i = 0; i < input.length; i++) {
                String s = input[i];

                for (int j = 0; j < s.length(); j++) {
                    ch = s.charAt(j);

                    if (ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch == 'o'
                            || ch == 'O' || ch == 'u' || ch == 'U')
                        vowels++;
                }
            }
            System.out.println("Vowels : " + vowels);

        } catch (Exception e) {
        }
    }

}

VowelThread.java

package lab2;


/**
 *
 * @author Shyam
 */

import java.io.IOException;

public class VowelThread  {

    public static void main(String[] args) 
                throws IOException {
        for (String str : args) {
            System.out.println(str);
        }
        Thread t1 = new Thread(new CountVowel(args));
        t1.start();
    }
}

I have tried different approach as below to enter string in cmd however I am not getting desire out put.

enter image description here

enter image description here

C:\Users\Shyam\Documents\NetBeansProjects\lab2\src>java VowelCounter hello hello see you in
Error: Could not find or load main class VowelCounter


C:\Users\Shyam\Documents\NetBeansProjects\lab2\src>javac -cp . lab2\VowelThread.java hello hello see you in london
error: Class names, 'hello,hello,see,you,in,london', are only accepted if annotation processing is explicitly requested
1 error

I would appreciate your help.

Shyam Bhimani
  • 1,310
  • 1
  • 22
  • 37
  • Just so you know, [counting can be done this way](http://stackoverflow.com/a/8910767/5743988). Using regex, yours would be `int count = str.replaceAll("(?i)[^aeiou]","").length();` – 4castle Jun 25 '16 at 01:01
  • 1
    Don't run compiler from `lab2` folder. Run from `src` folder using `javac -cp . lab2\VowelThread.java`. Or use an IDE. – Andreas Jun 25 '16 at 01:06
  • I tried from src folder and unfortunately it gave me error`{javac: file not}` found @Andreas – Shyam Bhimani Jun 25 '16 at 02:41
  • What file is not found? Show what you tried and show full error message (edit question and insert text, not image). – Andreas Jun 25 '16 at 02:43
  • I have updated added error i get when i run your way. I am not sure if I am running the way you asked me to. I am sorry I am complete Noob in this. @Andreas – Shyam Bhimani Jun 25 '16 at 05:04
  • 1
    `javac` is the *compiler*. You use it to compile your `.java` source files into `.class` files. Remove the `hello ...` arguments from the compiler command. --- *After* you have successfully compiled you Java classes, you can run your code using the `java -cp . lab2.VowelCounter hello hello see you in london` command. --- If you haven't even mastered these very initial steps of Java programming, you're not even close to ready to work with threads. Using an IDE will help you immensely. – Andreas Jun 25 '16 at 06:47

3 Answers3

1

Make sure you have both source files in the same directory before running the javac command. Then run the command as:

javac CountVowel.java VowelThread.java

Only after you have both classes compiled into .class files can you run the program, using something like:

java VowelThread arg1 arg2

However, you also have a couple problems in your multithreading implementation. You should continue to spawn a separate thread for each argument by putting the new Thread part inside the for loop, as I believe you had it before editing the question, but you should then pass that thread just the argument it was spawned for, rather than the entire argument list. Second, once you have that set up, you need to figure out a way for all the threads to update a common count.

Incidentally, it would probably be wise to learn more about single threaded Java before worrying about multithreaded Java.

Warren Dew
  • 8,790
  • 3
  • 30
  • 44
1

You don't really do what is expected as you don't create a new Thread for each provided argument, indeed you create only one Thread for all the arguments.

To implement it you could use FutureTask and make your class CountVowel implements Callable instead, something like this:

public class CountVowel implements Callable<Integer> {
    private final String input;

    public CountVowel(String input) {
        this.input = input;
    }

    public Integer call() {
        int vowels = 0;
        // Iterate over all the characters of the input String
        for (int j = 0; j < input.length(); j++) {
            // Lower case the current character as we need to ignore the case
            char ch = Character.toLowerCase(input.charAt(j));
            // Use a switch statement instead of an if as it is easier to read and faster
            switch (ch) {
                case 'a':
                case 'e':
                case 'o':
                case 'i':
                case 'u':
                    vowels++;
                    break;
            }
        }
        // Returns the sub total
        return vowels;
    }
}

The main class will then be something like this:

public class VowelThread {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // Create the list that will contain all the tasks
        List<FutureTask<Integer>> futures = new ArrayList<>();
        for (String str : args) {
            // Create a task for the current String
            FutureTask<Integer> future = new FutureTask<>(new CountVowel(str));
            // Add the task to the list of tasks
            futures.add(future);
            // Provide the task to a new Thread and start it
            new Thread(future).start();
        }
        int total = 0;
        // Iterate over all the tasks
        for (FutureTask<Integer> task : futures) {
            // Wait as long as it is needed to get the result of the current task
            total += task.get();
        }
        // Print the total of vowels found
        System.out.printf("Number of vowels: %d%n", total);
    }
}

About the second part of your issue, you need to launch your javac command from the src directory otherwise it cannot compile because your classes are in the package lab2 such that it should be in the directory lab2 from where you launch your javac command.

So assuming that you are in src, the expected commands are the following:

javac lab2\VowelThread.java 
java lab2.VowelThread Hello Hello see you in Italy in Venice

Output:

Number of vowels: 15
Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • Can you explain me what was the problem with my code ? – Shyam Bhimani Jun 25 '16 at 18:06
  • 1
    As explained in my answer you only launch one thread instead of one thread per argument, which is much harder to do as you need to implement a mechanism allowing to get the result from each thread which is solved here with FutureTask – Nicolas Filotto Jun 25 '16 at 19:58
1
import java.lang.*;

class MyThread extends Thread    
{
String input;
static int vowels;
MyThread(String input)
{
    this.input=input;
}
public void run()
{
    char ch;
    try
    {
        for(int i=0; i<input.length(); i++)
        {
            ch=input.charAt(i);
            if (ch == 'a' || ch == 'A' || ch == 'e' || ch == 'E' || ch == 'i' || ch == 'I' || ch == 'o'|| ch == 'O' || ch == 'u' || ch == 'U')
                vowels++;
        }
    }
    catch(Exception ie)
    {
    }
}
}

class Demo
{
public static void main(String args[])
{
    for(int i=0; i<args.length; i++)
    {
        new MyThread(args[i]).start();
    }
    System.out.println("Number of Vowels:\t"+MyThread.vowels);
}
}
ArK
  • 20,698
  • 67
  • 109
  • 136