字符串数组名称搜索

时间:2015-11-14 00:25:24

标签: java file java.util.scanner

所以我有一个文件,其中包含所有的总统 - 他们的名字,中间名首字母(如果有的话)和姓氏。

需要读入该文件,用户可以输入总统的名称进行搜索,并显示该总统。

如果用户按名字或姓氏搜索,而不是两者都搜索,我会显示总统。

例如,外部文件包含:

public class NameSearch {

    public static void main(String[] args) throws IOException {

        try {
            // read from presidents file
            Scanner presidentsFile = new Scanner(new File("Presidents.txt"));
            // scanner for user input
            Scanner keyboard = new Scanner(System.in);
            // create array list of each line in presidents file
            ArrayList<String> presidentsArrayList = new ArrayList<String>();

            // prompt user to enter a string to see if it matches with a president's name
            System.out.println("Enter a search string of letters to find a president match: ");
            // store user input
            String userInput = keyboard.nextLine();

            // add president file info to array list linesInPresidentFile
            while (presidentsFile.hasNextLine()) {
                presidentsArrayList.add(presidentsFile.nextLine());
            } // end while loop

            String presidentNamesArray[] = presidentsArrayList.toArray(new String[presidentsArrayList.size()]);
            String results = searchArray(presidentNamesArray, userInput);

            //System.out.println("\nThe presidents who have \"" + userInput + "\" as part of their name are: ");

        } catch (FileNotFoundException ex) {
            // print out error (if any) to screen
            System.out.println(ex.toString());

        } // end catch block

    } // end main

    // method to search for a specific value in an array
    public static String searchArray(String array[], String value) {

        for (int i = 0; i < array.length; i++) {
            if (array[i].toLowerCase().contains(value.toLowerCase())) {
                String splitter[] = array[i].split(" ,");
                System.out.println(Arrays.toString(splitter));
            }

        }
        return Arrays.toString(array);
    }

}

我需要用户能够键入名字,姓氏,或者姓名和名字,并获得所需的结果(日期与大部分时间无关)。

尝试了很多不同的事情,但如果用户按名字和姓氏搜索,就不能到达显示总统的位置。

这是我到目前为止所得到的:

void linkedList::swapTwoAdjacent(int num1, int num2) {
    node *temp1, *temp2, *temp3;


    temp1 = head;
    temp2 = temp1->next;

    if (head == NULL) {
        cout << "List is empty" << endl;
        return;
    }
    else if (head->next == NULL) {
        cout << "Swap not possible! List has only one node." << endl;
    }

    else if (temp1->data == num1 && temp2->data == num2) {      // if the nodes to swap are the first two nodes
                head->next = temp2->next;   // make the next of head point to the third node
                temp2->next = head;         // make the next of the second node point to head
                head = temp2;               // now make the second node the head
            }


    else {
        node *tempHolder1, *tempHolder2, *tempHolder3;  // holders for nodes in temps to make swapping easier

        // go through nodes in the list with three pointers
        // temp1->temp2->temp3
        // I'm using three pointers so that I always know the node before the two nodes I'm looking for

        for (temp1 = head, temp2 = temp1->next, temp3 = temp2->next; temp3 != NULL; temp1 = temp1->next, temp2 = temp1->next, temp3 = temp2->next) {
            // cout << "IN FOR" << endl;

            if (temp2->data == num1 && temp3->data == num2) { // if the two nodes are found

                // these are just placeholders to make swapping easier

                tempHolder1 = temp1;    // now temp1 is the node before the two nodes I want to swap
                tempHolder2 = temp2;    // temp2 is the first node
                tempHolder3 = temp3;    // temp3 is the second node

                temp1->next = tempHolder2->next;        // make the first node point to the third node
                temp2->next = tempHolder3->next;        // make the second node point to what's after the third node
                temp3->next = tempHolder2;              // make the third node point to the second node

                break;

            }

            else {
                continue;
            }
        }

    }

}

2 个答案:

答案 0 :(得分:2)

还有另一种方法可以实现这个。阅读文件输入并将它们存储为对象(可能是lname,fname和year的类)。通过这种方式,您可以从用户输入中搜索lname,将其与相应的fname(作为相同的对象)进行匹配。创建可以完成一次,搜索可以在while循环中完成,实现用户同意继续搜索。

//define your class like this:
static int i; //to keep a track of number of objects
public class dummy{
string fname;
string lname;
string year;
};

while the file content exists:
read the line
dummy dobj[i++] = new dummy();//allocate memory for the object 
split the different parameters (fname, lname, year) from the read line
put these read parameters into the object 
dobj[i].fname = first;
dobj[i].lname = second;
dobj[i].year = y;

//ask your user to enter the query in a specified format
//if he enters lname, compare your input to all the object's lname, and so on
//in case of lname && fname, compare your input to the lname first and then check for the corresponding objects fname, if they match.. display

实际上,有很多方法可以实现您想要编程的内容。您可以要求使用数组列表索引来解决它。如果以特定格式接收用户的输入,则可以将其映射到该列表中的索引。此外,如果要同时使用名字和姓氏,可以使用表示名字和姓氏的索引来自同一列表。

答案 1 :(得分:0)

您可能在使用名字和姓氏搜索时遇到问题的原因是您必须准确匹配您的输入(当然忽略大小写)。我的意思是如果您使用George Washington作为输入,则您的程序将找不到George,Washington,(1789-1797)行的匹配项。这是因为您的程序将George Washington视为一个字符串。注意:输入缺少逗号,因此不会将其视为George,Washington,(1789-1797)的子字符串。如果您使用George,Washington作为输入字符串,那么您的程序将打印乔治华盛顿线。您的程序只搜索输入字符串是否是文件中任何行的子字符串。它不会专门搜索名字或姓氏。如果您使用in作为输入字符串,那么您将获得与 gton中的George Wash D. Roosevelt中的Frankl 匹配。

您可以做的是获取输入数据并将其拆分并搜索每个术语。您可以接受与提供的所有条款相匹配的行,也可以接受至少一个提供的条款。

public static String searchArray(String array[], String value) {
    // Uses both blank spaces and commas as delimiters
    String[] terms = value.toLowerCase().Split("[ ,]"); 

    for (int i = 0; i < array.length; i++) {
        String line = array[i].toLowerCase();
        boolean printIfAllMatch = true;
        boolean printIfAtLeastOneMatches = false;
        for(int j = 0 ; j < terms.length; j++) {
            // Check that all terms are contained in the line
            printIfAllMatch &= line.Contains(terms[j]); 
            // Check that at least one term is in the line
            printIfAtLeastOneMatches |= line.Contains(terms[j]); 
        }

        String splitter[] = array[i].split(" ,");
        if (printIfAllMatch) {
            System.out.println(Arrays.toString(splitter));
        }
        if(printIfAtLeastOneMatches) {
            System.out.println(Arrays.toString(splitter));
        }

    }
    //I'm not sure why you're returning the original array as a string
    //I would think it would make more sense to return an Array of filtered data.
    return Arrays.toString(array);
}

这不会考虑名称排序。如果那是你想要的,那么我建议创建一个类并将文件中的每一行解析为一个新对象,并尝试匹配第一个名称提供的第一个术语和第二个术语。姓氏,或者那种效果。