控制台中的java编程简单的chatterbot?

pnwntuvh  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(370)

你好,我是一个业余程序员,所以请小心与我。
我不想进入swing/switch对话框编程,因此我想让它尽可能简单。不过,我也不希望我的代码有很多if-an-else语句。我在寻找更多的方法让聊天机器人更流畅。我尝试过搜索和理解字符串和数组,但是我仍然不知道如何在我的代码中实现它们。
这是我第一次尝试做一个简单的聊天机器人

import java.util.Scanner;

public class ChatBot {

    public static void main(String[] args) {
        System.out.println("");
        Scanner sc = new Scanner(System.in);
        System.out.println("Hello I'm your therapist for today! What's your name? \n");
        String n = sc.nextLine();
        System.out.println("Okay " + n + ", How are you?");

        while (true) {
            System.out.println(" ");
            String inputs = sc.nextLine();
            inputs = inputs.toUpperCase();

            if (inputs.indexOf("FINE") >= 0) {
                System.out.println("That's good to know " + n);
            }

            else if (inputs.indexOf("HI") >= 0) {
                System.out.println("Hello " + n);
            }

            else if (inputs.indexOf("HELP") >= 0) {
                System.out.println("If you seek help, listen to your heart! <3");
            }

            else if (inputs.indexOf("HELP ME") >= 1) {
                System.out.println("I will try my best helping you, what's your problem?");
            }

            // what if bot doesn't know the answer to fyour question/response?
            // The chatbot gives a random respond to unknown questions by the user
            // here the number of random responses are given 4, but in java we start at 0
            // I have made the number to 4, so that the responses can be from between 0 to 3
            // Also I have added Math.random utility and declared it to a double value
            // The "r" is now my random, and I make a new integar to calculate random
            // response
            // by calculating the r times num variables and thereby getting a random value.
            // that random value is declared to "rResponse" and therefore I have assigned
            // the
            // String response to answer/reply depending on the random number that's
            // generated
            // between 0-3
            else {
                final int num = 4;
                double r = Math.random();
                int rResponse = (int) (r * num);
                String response = "";

                if (rResponse == 0) {
                    response = "Hmmm...";
                }

                else if (rResponse == 1) {
                    response = "Okay?...";
                }

                else if (rResponse == 2) {
                    response = "I don't get it...";
                }

                else if (rResponse == 3) {
                    response = "I dont quite follow, I'm sorry. Try another question";
                }
                System.out.println(response);

            }
        }

    }

}

不管怎样,我的问题是

else if (inputs.indexOf("HELP ME") >= 1) {
                    System.out.println("I will try my best helping you, what's your problem?"); }
else if (inputs.indexOf("HELP") >= 0) {
                System.out.println("If you seek help, listen to your heart! <3"); }

这个代码是事实,我不能让它响应两个不同的用户输入,我希望机器人分别回答。例如,当你说“救救我”而不是“救命”时,我希望它有不同的React。
有什么建议或方法,我可以做这不同的?
另外,如果有人能让我知道如何用另一种方法,使用arraylist重做这一切?还是二维数组?如果对我这样的初学者来说不是太硬的话。不必做所有这些if和else语句,最简单的方法是什么?
先谢谢你。

3j86kqsm

3j86kqsm1#

我假设您理解类、方法和字段。如果你不这样做,这个解释就没有任何意义了。
我们将使用类和 java.util.List 接口。
第一步是构造一个getter/setter类来保存响应和 List 下一个问题的索引。
这是那个班。

public class Response {

    private final String response;

    private final int responseQuestion;

    public Response(String response, int responseQuestion) {
        this.response = response.toLowerCase();
        this.responseQuestion = responseQuestion;
    }

    public boolean doesResponseMatch(String responseString) {
        return responseString.toLowerCase().contains(getResponse());
    }

    public String getResponse() {
        return response;
    }

    public int getResponseQuestion() {
        return responseQuestion;
    }

}

这个 doesResponseMatch 方法确定 responseString 由用户键入的包含响应 String .
我们将响应保存为小写 String 并转换用户 responseString 以使contains测试独立于大小写。
这个类的其余部分是一个典型的getter/setter类。
下一步是创建一个包含问题的类,一个 List 可能的响应,以及默认响应。如果所有可能的响应都不匹配,则使用默认响应。

public class Question {

    private final String question;

    private final Response defaultResponse;

    private List<Response> possibleResponses;

    public Question(String question, Response defaultResponse) {
        this.question = question;
        this.defaultResponse = defaultResponse;
        this.possibleResponses = new ArrayList<>();
    }

    public void addPossibleResponse(Response response) {
        this.possibleResponses.add(response);
    }

    public Response getPossibleResponse(String responseString) {
        for (Response response : this.possibleResponses) {
            if (response.doesResponseMatch(responseString)) {
                return response;
            }
        }

        return this.defaultResponse;
    }

    public String getQuestion() {
        return question;
    }

}

getpossibleresponse方法返回匹配的响应,如果没有匹配,则返回默认响应。
问题可以包含零个、一个或多个匹配的回答。每个回答可以指向不同的问题索引。
我们使用 java.util.ArrayList 举行会议 List . 因为我们要一次添加所有问题,所以数组列表是保存树的适当结构。
下一步是创建一个类来保存我们的树结构,它将是一个 ListQuestion 示例。

public class ResponseTree {

    private List<Question> questions;

    public ResponseTree() {
        this.questions = new ArrayList<>();
        addQuestionFactory();
    }

    private void addQuestionFactory() {
        Response defaultResponse = new Response("", 0);
        String question = "I don't understand your response.";
        addQuestion(question, defaultResponse);

        // Add your additional questions / responses here.
        // Using a List means we can point to any question by it's 
        // location number from 0 to List size() - 1.
        // This is a tree structure, stored in a List.
    }

    private void addQuestion(String question, Response defaultResponse) {
        this.questions.add(new Question(question, defaultResponse));
    }
}

这个 addQuestionFactory 是一个单独的方法,因为它将增长到包含所有您想要回答的chatbot问题。我已经包括了第一个明显的问题。
您可以通过编写chatbot的其余部分来测试此代码。任何回答都将由第一个问题来回答。编写完chatbot的其余部分后,可以向工厂方法添加问题和响应。
通过使用类,我们创建了如下树结构:

Tree (List)
    Question
        String
        List of possible responses
        Default response

Response
    String
    Index pointer

通过使用类,我们可以隐藏一些复杂性,使代码更易于理解。

ddrv8njm

ddrv8njm2#

在这种情况下,你应该求助于 equals :

else if ("HELP ME".equals(inputs)) {
                System.out.println("I will try my best helping you, what's your problem?"); 
} else if ("HELP".equals(inputs)) {
     System.out.println("If you seek help, listen to your heart! <3"); 
}

与常量字符串比较的一般做法是将字符串常量放在第一位,变量放在第二位,以防出现npe(nullpointerexception) inputs 为空。
回到你的问题上来,我想你可以用 HashMap 避免 if-else 声明:

HashMap<> handlers = new HashMap<String, Runnable>();
handlers.add("FINE", () -> {
    System.out.println("That's good to know " + n);
});

.... add other handlers.

do while {

    Get your handler from  handlers and call run on it.
    If no handler not found, try randome response.
}

它的效率比 indexOf 以及 equals 操作。
顺便说一句,springshell是编写shell应用程序的良好开端。

相关问题