Java算法:华为机试算法第二版(下),华为算法Java版

牛客网-华为机试练习题 73
题目描述

公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?

详细描述:

接口说明

原型:

int GetResult(vector &list)

输入参数:

​ 无

输出参数(指针指向的内存区域保证有效):

​ list 鸡翁、鸡母、鸡雏组合的列表

返回值:

​ -1 失败

​ 0 成功

输入描述:
输入任何一个整数,即可运行程序。
输出描述:


示例1

 输入

1
输出

0 25 75
4 18 78
8 11 81
12 4 84
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while (br.readLine() != null) {
            int i;
            int j;
            for (i = 0; i <= 20; ++i) {
                for (j = 0; j <= 100 - i; ++j) {
                    int k = 100 - i - j;
                    if ((k % 3 == 0) && (5 * i + 3 * j + k / 3 == 100))
                        System.out.println(i + " " + j + " " + k);
                }
            }
        }
    }
}

牛客网-华为机试练习题 74
题目描述

根据输入的日期,计算是这一年的第几天。。

详细描述:

输入某年某月某日,判断这一天是这一年的第几天?。


接口设计及说明:

 /*****************************************************************************
 Description   : 数据转换
 Input Param   : year 输入年份
                Month 输入月份
                Day 输入天
                    
 Output Param  :
 Return Value  : 成功返回0,失败返回-1(如:数据错误)
 *****************************************************************************/
 public static int iConverDateToDay(int year, int month, int day)
 {
     /* 在这里实现功能,将结果填入输入数组中*/ 
     return 0;
 }
 
 /*****************************************************************************
 Description   : 
 Input Param   :
                    
 Output Param  :
 Return Value  : 成功:返回outDay输出计算后的第几天;
                                           失败:返回-1
 *****************************************************************************/
 public static int getOutDay()
 {
  return 0;
 }

输入描述:
输入三行,分别是年,月,日
输出描述:
成功:返回outDay输出计算后的第几天;
                                           失败:返回-1


示例1

输入

2012

12

31


输出

366
解决代码:
//
//输入年月日,返回天数
//1-31 2-28 3-31 4-30 5-31 6-30 7-31 8-31 9-30 10-31 11-30 12-31

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static int getAllDay(int year, int month, int day) {
        int[] dayary = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //判断闰年
        if (year % 4 == 0) dayary[1] = 29;
        int total = 0;
        for (int i = 0; i < month - 1; i++) {
            total += dayary[i];
        }
        total += day;
        return total;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            String[] lineary = line.split(" ");
            int year = Integer.parseInt(lineary[0]);
            int month = Integer.parseInt(lineary[1]);
            int day = Integer.parseInt(lineary[2]);
            System.out.println(getAllDay(year, month, day));
        }
    }
}
牛客网-华为机试练习题 75
题目描述

在命令行输入如下命令:

xcopy /s c:\ d:\,

各个参数如下: 

参数1:命令字xcopy 

参数2:字符串/s

参数3:字符串c:\

参数4: 字符串d:\

请编写一个参数解析程序,实现将命令行各个参数解析出来。

解析规则: 

1.参数分隔符为空格 
2.对于用“”包含起来的参数,如果中间有空格,不能解析为多个参数。比如在命令行输入xcopy /s “C:\program files” “d:\”时,参数仍然是4个,第3个参数应该是字符串C:\program files,而不是C:\program,注意输出参数时,需要将“”去掉,引号不存在嵌套情况。
3.参数不定长 
4.输入由用例保证,不会出现不符合要求的输入 
 
输入描述:
输入一行字符串,可以有空格
输出描述:
输出参数个数,分解后的参数,每个参数都独占一行

示例1

输入

xcopy /s c:\\ d:\\


输出

4
xcopy
/s
c:\\
d:\\
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        String[] strings = s.split(" ");
        List<String> list = new ArrayList<String>();
        for (int i = 0; i < strings.length; ) {
            if (strings[i].charAt(0) != '"') {
                list.add(strings[i]);
                ++i;
            } else {
                if (strings[i].charAt(strings[i].length() - 1) == '"') {
                    list.add(strings[i].substring(1, strings[i].length() - 1));
                    ++i;
                } else {
                    StringBuilder sb = new StringBuilder();
                    sb.append(strings[i].substring(1) + " ");
                    ++i;
                    while (strings[i].charAt(strings[i].length() - 1) != '"') {
                        sb.append(strings[i] + " ");
                        ++i;
                    }
                    sb.append(strings[i], 0, strings[i].length() - 1);
                    ++i;
                    list.add(sb.toString());
                }
            }
        }
        System.out.println(list.size());
        for (String value : list) {
            System.out.println(value);
        }
    }
}

牛客网-华为机试练习题 76
题目描述

题目标题:

计算两个字符串的最大公共字串的长度,字符不区分大小写

详细描述:

接口说明

原型:

int getCommonStrLength(char * pFirstStr, char * pSecondStr);

输入参数:

​     char * pFirstStr //第一个字符串

​     char * pSecondStr//第二个字符串
输入描述:
输入两个字符串
输出描述:
输出一个整数

示例1

输入

asdfas werasdfaswer
 输出

6
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String string1 = "";
        while ((string1 = bufferedReader.readLine()) != null) {
            String string2 = bufferedReader.readLine();
            char[] str1 = string1.toCharArray();
            char[] str2 = string2.toCharArray();
            int[][] dp = new int[str1.length][str2.length];
            for (int i = 0; i < str1.length; i++) {
                if (str1[i] == str2[0]) {
                    dp[i][0] = 1;
                }
            }
            for (int j = 1; j < str2.length; j++) {
                if (str2[j] == str1[0]) {
                    dp[0][j] = 1;
                }
            }
            int max = 0;
            for (int i = 1; i < str1.length; i++) {
                for (int j = 1; j < str2.length; j++) {
                    if (str1[i] == str2[j]) {
                        dp[i][j] = dp[i - 1][j - 1] + 1;
                    }
                    max = Math.max(max, dp[i][j]);
                }
            }
            System.out.println(max);
        }
    }
}

牛客网-华为机试练习题 77
题目描述

验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。

例如:

1^3=1 

2^3=3+5 

3^3=7+9+11 

4^3=13+15+17+19 

接口说明

原型:

 /*
 功能: 验证尼科彻斯定理,即:任何一个整数m的立方都可以写成m个连续奇数之和。
 原型:
     int GetSequeOddNum(int m,char * pcSequeOddNum);
 输入参数:
     int m:整数(取值范围:1~100)
    
 返回值:
     m个连续奇数(格式:“7+9+11”);
 */

 public String GetSequeOddNum(int m)
 {
     /*在这里实现功能*/

​     return null;
 }

输入描述:
输入一个int整数
输出描述:
输出分解后的string

示例1
输入

6
输出

31+33+35+37+39+41
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int n = Integer.parseInt(line);
            getRes(n);
        }
    }

    public static void getRes(int n) {
        String str = "";
        if (n % 2 == 0) { // n为偶数
            int mid = (int) (Math.pow(n, 3) / n);
            str = (mid - 1) + "+" + (mid + 1);
            int T = n / 2;
            for (int i = 1; i < T; i++) {
                str = (mid - (2 * i) - 1) + "+" + str + "+" + (mid + (2 * i) + 1);
            }
        } else { // n为奇数
            int mid = (int) (Math.pow(n, 3) / n);
            str = mid + "";
            int T = n / 2;
            for (int i = 0; i < T; i++) {
                str = (mid - 2 * (i + 1)) + "+" + str + "+" + (mid + 2 * (i + 1));
            }
        }
        System.out.println(str);
    }
}
牛客网-华为机试练习题 78
题目描述

给定一个正整数N代表火车数量,0<N<10,接下来输入火车入站的序列,一共N辆火车,每辆火车以数字1-9编号。要求以字典序排序输出火车出站的序列号。

输入描述:
有多组测试用例,每一组第一行输入一个正整数N(0<N<10),第二行包括N个正整数,范围为1到9。
输出描述:
输出以字典序从小到大排序的火车出站序列号,每个编号以空格隔开,每个输出序列换行,具体见sample。

示例1

输入

3
1 2 3
输出

1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
解决代码:
import java.util.*;

public class Main {
    private static Stack<String> stack1 = new Stack<>();
    private static Stack<String> stack2 = new Stack<>();
    private static List<String> list = new ArrayList<>();

    public static void ff(String str) {
        if (stack1.isEmpty() && stack2.isEmpty()) {
            list.add(str.trim());
            return;
        }
        if (!stack2.isEmpty()) {
            String str1 = stack2.pop();
            ff(str + " " + str1);
            stack2.push(str1);
        }
        if (!stack1.isEmpty()) {
            String str2 = stack1.pop();
            stack2.push(str2);
            ff(str);
            stack2.pop();
            stack1.push(str2);
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int n = scanner.nextInt();
            scanner.nextLine();
            String str = scanner.nextLine();
            String[] ss = str.split(" ");
            for (int i = ss.length - 1; i >= 0; i--) stack1.push(ss[i]);
            ff("");
            Collections.sort(list);
            for (String s : list) System.out.println(s);
        }
    }
}
牛客网-华为机试练习题 79
题目描述
请设计一个算法完成两个超长正整数的加法。

接口说明

 /*
 请设计一个算法完成两个超长正整数的加法。
 输入参数:
 String addend:加数
 String augend:被加数
 返回值:加法结果
 */

 public String AddLongInteger(String addend, String augend)
 {
     /*在这里实现功能*/
  

  return null;     
 }

输入描述:
输入两个字符串数字
输出描述:
输出相加后的结果,string型


示例1

 输入

99999999999999999999999999999999999999999999999999
1
输出

100000000000000000000000000000000000000000000000000
解决代码:
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        String str1;
        while ((str1 = bReader.readLine()) != null) {
            String str2 = bReader.readLine();
            StringBuilder sb1 = new StringBuilder(str1);
            StringBuilder sb2 = new StringBuilder(str2);
            int len1 = sb1.length();
            int len2 = sb2.length();
            if (len1 > len2) {
                for (int i = 0; i < len1 - len2; i++) sb2.insert(0, "0");
            } else {
                for (int i = 0; i < len2 - len1; i++) sb1.insert(0, "0");
            }
            StringBuilder sb = new StringBuilder();
            int temp = 0;
            for (int i = sb1.length() - 1; i >= 0; i--) {
                int m = sb1.charAt(i) - '0';
                int n = sb2.charAt(i) - '0';
                int sum = m + n + temp;
                sb.insert(0, sum % 10);
                temp = sum / 10;
            }
            if (temp != 0) sb.insert(0, temp);
            System.out.println(sb.toString());
        }
    }

}
牛客网-华为机试练习题 80
题目描述

对于不同的字符串,我们希望能有办法判断相似程度,我们定义了一套操作方法来把两个不相同的字符串变得相同,具体的操作方法如下:

1 修改一个字符,如把“a”替换为“b”。

2 增加一个字符,如把“abdd”变为“aebdd”。

3 删除一个字符,如把“travelling”变为“traveling”。

比如,对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加和减少一个“g”的方式来达到目的。上面的两种方案,都只需要一次操作。把这个操作所需要的次数定义为两个字符串的距离,而相似度等于“距离+1”的倒数。也就是说,“abcdefg”和“abcdef”的距离为1,相似度为1/2=0.5.

给定任意两个字符串,你是否能写出一个算法来计算出它们的相似度呢?

请实现如下接口

 /* 功能:计算字符串的相似度
  \* 输入:pucAExpression/ pucBExpression:字符串格式,如: "abcdef"
  \* 返回:字符串的相似度,相似度等于“距离+1”的倒数,结果请用1/字符串的形式,如1/2
  */
 public static  String  calculateStringDistance(String expressionA, String expressionB)
 {
     /* 请实现*/
     return null;
 }


约束:

1、PucAExpression/ PucBExpression字符串中的有效字符包括26个小写字母。

2、PucAExpression/ PucBExpression算术表达式的有效性由调用者保证;
3、超过result范围导致信息无法正确表达的,返回null。
输入描述:
输入两个字符串
输出描述:
输出相似度,string类型

示例1

输入

abcdef
abcdefg

输出

1/2
解决代码:
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader in = new BufferedReader(
                new InputStreamReader(System.in)
        );
        String s1 = "";
        while (null != (s1 = in.readLine())) {
            //将两个输入字符串转为数组
            String s2 = in.readLine();
            char[] cs1 = s1.toCharArray();
            char[] cs2 = s2.toCharArray();
            int[][] dp = new int[s1.length() + 1][s2.length() + 1];
            //用动态规划的方式获取一个数组变为另一个数组的步骤次数
            //初始化二维数组
            for (int row = 1; row <= s1.length(); row++) {
                dp[row][0] = row;
            }
            for (int col = 1; col <= s2.length(); col++) {
                dp[0][col] = col;
            }
            //动态规划
            for (int row = 1; row <= s1.length(); row++) {
                for (int col = 1; col <= s2.length(); col++) {
                    if (cs1[row - 1] == cs2[col - 1]) {
                        dp[row][col] = dp[row - 1][col - 1];
                    } else {
                        int min1 = Math.min(dp[row - 1][col], dp[row][col - 1]) + 1;
                        dp[row][col] = Math.min(min1, dp[row - 1][col - 1] + 1);

                    }
                }
            }
            System.out.println("1/" + (dp[s1.length()][s2.length()] + 1));
        }
    }
}
牛客网-华为机试练习题 81
题目描述

题目标题:

将两个整型数组按照升序合并,并且过滤掉重复数组元素[注: 题目更新了。输出之后有换行]

详细描述:

接口说明

原型:

voidCombineBySort(int* pArray1,intiArray1Num,int* pArray2,intiArray2Num,int* pOutputArray,int* iOutputNum);

输入参数:

int* pArray1 :整型数组1

intiArray1Num:数组1元素个数

int* pArray2 :整型数组2

intiArray2Num:数组2元素个数

输出参数(指针指向的内存区域保证有效):

int* pOutputArray:合并后的数组

int* iOutputNum:合并后数组元素个数

返回值:

void
输入描述:
输入说明,按下列顺序输入:
1 输入第一个数组的个数
2 输入第一个数组的数值
3 输入第二个数组的个数
4 输入第二个数组的数值
输出描述:
输出合并之后的数组


示例1

 输入

3
1 2 5
4
-1 0 3 2
输出


-101235
解决代码:
import java.util.Arrays;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int numa = in.nextInt();
            int[] a = new int[numa];
            for (int i = 0; i < numa; i++) {
                a[i] = in.nextInt();
            }
            int numb = in.nextInt();
            int[] b = new int[numb];
            for (int i = 0; i < numb; i++) {
                b[i] = in.nextInt();
            }
            System.out.print(combineBySort(a, b));
        }
        in.close();
    }

    public static String combineBySort(int[] a, int[] b) {
        int[] c = new int[a.length + b.length];
        Arrays.sort(a);
        Arrays.sort(b);
        int aindex = 0;
        int bindex = 0;
        int cindex = 0;
        while (aindex < a.length && bindex < b.length) {
            if (a[aindex] < b[bindex]) {
                c[cindex] = a[aindex];
                aindex++;
            } else if (a[aindex] > b[bindex]) {
                c[cindex] = b[bindex];
                bindex++;
            } else {
                c[cindex] = a[aindex];
                aindex++;
                bindex++;
            }
            cindex++;
        }
        for (int i = aindex; i < a.length; i++) {
            if (a[i] != c[cindex - 1]) {
                c[cindex] = a[i];
                cindex++;
            }
        }
        for (int i = bindex; i < b.length; i++) {
            if (b[i] != c[cindex - 1]) {
                c[cindex] = b[i];
                cindex++;
            }
        }
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < cindex; i++) {
            builder.append(c[i]);
        }
        return builder.toString();
    }

}

牛客网-华为机试练习题 82
题目描述

题目标题:

判断短字符串中的所有字符是否在长字符串中全部出现

详细描述:

接口说明

原型:

boolIsAllCharExist(char* pShortString,char* pLongString);

输入参数:

​    char* pShortString:短字符串

​    char* pLongString:长字符串

输入描述:
输入两个字符串。第一个为短字符,第二个为长字符。
输出描述:
返回值:

示例1

输入

bc
abc
输出

true
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = "";
        while ((str = br.readLine()) != null) {
            String str2 = br.readLine();
            int i;
            for (i = 0; i < str.length(); i++) {
                if (str2.indexOf(str.charAt(i)) == -1) {
                    System.out.println("false");
                    i--;
                    break;
                }
            }
            if (i == str.length()) {
                System.out.println(true);
            }
        }
        br.close();
    }
}


牛客网-华为机试练习题 83
题目描述

分子为1的分数称为埃及分数。现输入一个真分数(分子比分母小的分数,叫做真分数),请将该分数分解为埃及分数。如:8/11 = 1/2+1/5+1/55+1/110。


接口说明

 /*
 功能: 将分数分解为埃及分数序列
 输入参数:
     String pcRealFraction:真分数(格式“8/11”)
 返回值:
     String pcEgpytFraction:分解后的埃及分数序列(格式“1/2+1/5+1/55+1/100”)
 */

 public static String  ConvertRealFractToEgpytFract(String pcRealFraction)
 {
  return null;
 }

输入描述:
输入一个真分数,String型
输出描述:
输出分解后的string


示例1

输入


8/11
 输出


1/2+1/5+1/55+1/110
解决代码:
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            String str = in.next();
            Egyptsocre(str);
        }
    }

    public static void Egyptsocre(String str) {
        String[] parts = str.split("/");
        int a = Integer.parseInt(parts[0]);//分子
        int b = Integer.parseInt(parts[1]);//分母
        StringBuilder sb = new StringBuilder();
        int c;
        while (a != 1) {
            if (b % (a - 1) == 0) {
                sb.append("1/").append(b / (a - 1)).append('+');
                a = 1;
            } else {
                c = b / a + 1; //重要点
                sb.append("1/").append(c).append('+');
                a = a * c - b;
                b = c * b;          //计算分式子
                if (b % a == 0) {
                    b = b / a;
                    a = 1;
                }
            }
        }
        sb.append("1/").append(b);
        System.out.println(sb.toString());
    }

}

牛客网-华为机试练习题 84
题目描述

​ 有一个数据表格为二维数组(数组元素为int类型),行长度为ROW_LENGTH,列长度为COLUMN_LENGTH。对该表格中数据的操作可以在单个单元内,也可以对一个整行或整列进行操作,操作包括交换两个单元中的数据;插入某些行或列。

​ 请编写程序,实现对表格的各种操作,并跟踪表格中数据在进行各种操作时,初始数据在表格中位置的变化轨迹。

详细要求:

1.数据表规格的表示方式为“行*列”, 数据表元素的位置表示方式为[行,列],行列均从0开始编号

2.数据表的最大规格为9行*9列,对表格进行操作时遇到超出规格应该返回错误

3.插入操作时,对m*n表格,插入行号只允许0m,插入列号只允许0n。超出范围应该返回错误

4.只需记录初始表格中数据的变化轨迹,查询超出初始表格的数据应返回错误

例如: 初始表格为44,可查询的元素范围为[0,0]~[3,3],假设插入了第2行,数组变为54,查询元素[4,0]时应该返回错误

5.查询数据要求返回一个链表,链表中节点的顺序即为该查询的数据在表格中的位置变化顺序(需包含初始位置)

输入描述:
输入数据按下列顺序输入:
1 表格的行列值
2 要交换的两个单元格的行列值
3 输入要插入的行的数值
4 输入要插入的列的数值
5 输入要获取运动轨迹的单元格的值
输出描述:
输出按下列顺序输出:
1 初始化表格是否成功,若成功则返回0, 否则返回-1
2 输出交换单元格是否成功
3 输出插入行是否成功
4 输出插入列是否成功
5 输出要查询的运动轨迹的单元查询是否成功

示例1

输入


3 4
1 1
0 1
2
1
2 2

输出

0
0
0
0
0
解决代码:
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            int[] arr = new int[10];
            for (int i = 0; i < 10; i++) {
                arr[i] = scanner.nextInt();
            }
            System.out.print(solve(arr));
        }
        scanner.close();
    }

    private static String solve(int[] arr) {
        int[] result = new int[5];
        // 检查行列值
        if (arr[0] < 0 || arr[0] > 9 || arr[1] < 0 || arr[1] > 9) {
            result[0] = -1;
        } else {
            result[0] = 0;
        }
// 检查交换单元格是否合法
        if (result[0] == 0 && (arr[2] >= 0 && arr[2] < arr[0] && arr[3] >= 0 && arr[3] < arr[1])
                && (arr[4] >= 0 && arr[4] < arr[0] && arr[5] >= 0 && arr[5] < arr[1])) {
            result[1] = 0;
        } else {
            result[1] = -1;
        }
// 检查插入行是否成功
        if (result[0] == 0 && (arr[6] >= 0 && arr[6] < arr[0])) {
            result[2] = 0;
        } else {
            result[2] = -1;
        }
// 检查插入列是否成功
        if (result[0] == 0 && (arr[7] >= 0 && arr[7] < arr[1])) {
            result[3] = 0;
        } else {
            result[3] = -1;
        }
// 检查访问是否成功
        if (result[0] == 0 && (arr[8] >= 0 && arr[8] < arr[0] && arr[9] >= 0 && arr[9] < arr[1])) {
            result[4] = 0;
        } else {
            result[4] = -1;
        }
        StringBuilder b = new StringBuilder();
        for (int i : result) {
            b.append(i).append('\n');
        }
        return b.toString();
    }
}


牛客网-华为机试练习题 85
题目描述

找出给定字符串中大写字符(即’A’-‘Z’)的个数

接口说明

原型:int CalcCapital(String str);

返回值:int

输入描述:
输入一个String数据
输出描述:
输出string中大写字母的个数

示例1

输入

add123#$%#%#O
输出

1
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            System.out.println(CalcCapital(line));
        }
    }

    private static int CalcCapital(String line) {
        int sum = 0;
        for (int i = 0; i < line.length(); ++i)
            if (line.charAt(i) >= 'A' && line.charAt(i) <= 'Z') ++sum;
        return sum;
    }
}
牛客网-华为机试练习题 86
题目描述

Catcher 是MCA国的情报员,他工作时发现敌国会用一些对称的密码进行通信,比如像这些ABBA,ABA,A,123321,但是他们有时会在开始或结束时加入一些无关的字符以防止别国破解。比如进行下列变化 ABBA->
12ABBA,ABA->ABAKK,123321->51233214
。因为截获的串太长了,而且存在多种可能的情况(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量实在是太大了,他只能向电脑高手求助,你能帮Catcher找出最长的有效密码串吗?

(注意:记得加上while处理多个测试用例)

输入描述:
输入一个字符串
输出描述:
返回有效密码串的最大长度

示例1

输入

ABBA

输出

4
解决代码:
import java.io.*;

public class Main {
    public static int getLongestStr(String str) {
        int maxLen = -1;
        //奇数
        for (int i = 0; i < str.length(); ++i) {
            int j = i - 1;
            int k = i + 1;
            while (j >= 0 && k < str.length() && str.charAt(j) == str.charAt(k)) {
                if ((k - j + 1) > maxLen) maxLen = k - j + 1;
                j--;
                k++;
            }
        }
        for (int i = 0; i < str.length(); ++i) {
            int j = i;
            int k = i + 1;
            while (j >= 0 && k < str.length() && str.charAt(j) == str.charAt(k)) {
                if ((k - j + 1) > maxLen) maxLen = k - j + 1;
                j--;
                k++;
            }
        }
        return maxLen;
    }

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = br.readLine()) != null && !("".equals(str))) {
            int num = getLongestStr(str);
            System.out.println(num);
        }
    }
}

牛客网-华为机试练习题 87
题目描述

功能: 求一个byte数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个1

输入: 一个byte型的数字

输出: 无

返回: 对应的二进制数字中1的最大连续数

输入描述:
输入一个byte数字
输出描述:
输出转成二进制之后连续1的个数


示例1

 输入

3
输出

2
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int n = Integer.parseInt(line);
            getOneNumber(n);
        }
    }

    public static void getOneNumber(int n) {
        char[] chs = Integer.toBinaryString(n).toCharArray();
        int count = 0;
        for (int i = 0; i < chs.length; ) {
            while (i < chs.length && chs[i] != '1') {
                i++;
            }
            int j = i;
            while (j < chs.length && chs[j] == '1') {
                j++;
                if ((j - i) > count) {
                    count = j - i;
                }
            }
            i = j;
        }
        System.out.println(count);
    }
}

牛客网-华为机试练习题 88
题目描述

密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分。

​       一、密码长度:

​       5 分: 小于等于4 个字符

​       10 分: 5 到7 字符

​       25 分: 大于等于8 个字符

​       二、字母:

​       0 分: 没有字母

​       10 分: 全都是小(大)写字母

​       20 分: 大小写混合字母

​       三、数字:

​       0 分: 没有数字

​       10 分: 1 个数字

​       20 分: 大于1 个数字

​       四、符号:

​       0 分: 没有符号

​       10 分: 1 个符号

​       25 分: 大于1 个符号

​       五、奖励:

​       2 分: 字母和数字

​       3 分: 字母、数字和符号

​       5 分: 大小写字母、数字和符号

​       最后的评分标准:

​       \>= 90: 非常安全

​       \>= 80: 安全(Secure)

​       \>= 70: 非常强

​       \>= 60: 强(Strong)

​       \>= 50: 一般(Average)

​       \>= 25: 弱(Weak)

​       \>= 0:  非常弱


对应输出为:

  VERY_WEAK,

   WEAK,    

   AVERAGE,    

   STRONG,     

   VERY_STRONG,

   SECURE,     

   VERY_SECURE 

​       请根据输入的密码字符串,进行安全评定。

​       注:

​       字母:a-z, A-Z

​       数字:-9

​       符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)

​       !"#$%&'()*+,-./     (ASCII码:x21~0x2F)

​       :;<=>?@             (ASCII<=><=><=><=><=>码:x3A~0x40)

​       [\]^_`              (ASCII码:x5B~0x60)

  {|}~                (ASCII码:x7B~0x7E)

接口描述:

 

 Input Param 
      String pPasswordStr:    密码,以字符串方式存放。

 Return Value
   根据规则评定的安全等级。

 

 
 public static Safelevel GetPwdSecurityLevel(String pPasswordStr)
 {
     /*在这里实现功能*/
  return null;
 }

输入描述:
输入一个string的密码
输出描述:
输出密码等级

示例1

输入

38$@NoNoNo

输出

VERY_SECURE
解决代码:
import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            GetPwdSecurityLevel(line);
        }
    }

    private static void GetPwdSecurityLevel(String line) {
        int lenGirad = 0;
        int numGirad = 0;
        int charGirad = 0;
        int otherCharGirad = 0;
        int rewardGirad = 0;
        char[] chs = line.toCharArray();
        if (chs.length <= 4) lenGirad = 5;
        else if (chs.length <= 7) lenGirad = 10;
        else lenGirad = 25;
        int Numbercount = 0;
        int LowerCcount = 0;
        int UpperCcount = 0;
        int otherCcount = 0;
        for (char ch : chs) {
            if (ch >= 'a' && ch <= 'z') ++LowerCcount;
            else if (ch >= 'A' && ch <= 'Z') ++UpperCcount;
            else if (ch >= '0' && ch <= '9') ++Numbercount;
            else ++otherCcount;
        }
        if (Numbercount == 1) numGirad = 10;
        else numGirad = 20;
        if (LowerCcount == 0 || UpperCcount == 0) charGirad = 10;
        else charGirad = 20;
        if (otherCcount == 1) otherCharGirad = 10;
        else otherCharGirad = 25;
        if (LowerCcount > 0 && UpperCcount > 0 && Numbercount > 0 && otherCcount > 0) rewardGirad = 5;
        else if ((LowerCcount > 0 || UpperCcount > 0) && Numbercount > 0 && otherCcount > 0) rewardGirad = 3;
        else if ((LowerCcount > 0 || UpperCcount > 0) && Numbercount > 0) rewardGirad = 2;
        int sumGriad = lenGirad + numGirad + charGirad + otherCharGirad + rewardGirad;
        if (sumGriad >= 90) System.out.println("VERY_SECURE");
        else if (sumGriad >= 80) System.out.println("SECURE");
        else if (sumGriad >= 70) System.out.println("VERY_STRONG");
        else if (sumGriad >= 60) System.out.println("STRONG");
        else if (sumGriad >= 50) System.out.println("AVERAGE");
        else System.out.println("WEAK");
    }
}

牛客网-华为机试练习题 89
题目描述

扑克牌游戏大家应该都比较熟悉了,一副牌由54张组成,含3~A、2各4张,小王1张,大王1张。牌面从小到大用如下字符和字符串表示(其中,小写joker表示小王,大写JOKER表示大王): 3 4 5 6 7 8 9 10 J Q K A 2
joker JOKER 输入两手牌,两手牌之间用"-“连接,每手牌的每张牌以空格分隔,”-"两边没有空格,如:4 4 4 4-joker JOKER。 请比较两手牌大小,输出较大的牌,如果不存在比较关系则输出ERROR。 基本规则:
(1)输入每手牌可能是个子、对子、顺子(连续5张)、三个、炸弹(四个)和对王中的一种,不存在其他情况,由输入保证两手牌都是合法的,顺子已经从小到大排列;
(2)除了炸弹和对王可以和所有牌比较之外,其他类型的牌只能跟相同类型的存在比较关系(如,对子跟对子比较,三个跟三个比较),不考虑拆牌情况(如:将对子拆分成个子);
(3)大小规则跟大家平时了解的常见规则相同,个子、对子、三个比较牌面大小;顺子比较最小牌大小;炸弹大于前面所有的牌,炸弹之间比较牌面大小;对王是最大的牌;

(4)输入的两手牌不会出现相等的情况。

输入描述:
输入两手牌,两手牌之间用"-"连接,每手牌的每张牌以空格分隔,"-"两边没有空格,如 4 4 4 4-joker JOKER。
输出描述:
输出两手牌中较大的那手,不含连接符,扑克牌顺序不变,仍以空格隔开;如果不存在比较关系则输出ERROR。

示例1

输入

4 4 4 4-joker JOKER

 输出


joker JOKER
解决代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str = null;
        while ((str = bf.readLine()) != null) {
            String[] ss = str.split("-");
            if (ss[0].equals("joker JOKER") || ss[1].equals("joker JOKER")) {
                System.out.println("joker JOKER");
                continue;
            }
            String[] str0 = ss[0].split(" ");
            String[] str1 = ss[1].split(" ");
            for (int i = 0; i < str0.length; i++) {
                if (str0[i].equals("J")) {
                    str0[i] = "11";
                    continue;
                }
                if (str0[i].equals("Q")) {
                    str0[i] = "12";
                    continue;
                }
                if (str0[i].equals("K")) {
                    str0[i] = "13";
                    continue;
                }
                if (str0[i].equals("A")) {
                    str0[i] = "14";
                    continue;
                }
                if (str0[i].equals("2")) {
                    str0[i] = "15";
                }
            }
            for (int i = 0; i < str1.length; i++) {
                if (str1[i].equals("J")) {
                    str1[i] = "11";
                    continue;
                }
                if (str1[i].equals("Q")) {
                    str1[i] = "12";
                    continue;
                }
                if (str1[i].equals("K")) {
                    str1[i] = "13";
                    continue;
                }
                if (str1[i].equals("A")) {
                    str1[i] = "14";
                    continue;
                }
                if (str1[i].equals("2")) {
                    str1[i] = "15";
                }
            }
            int len1 = str0.length, len2 = str1.length;
            if (len1 == 4 || len2 == 4) {
                if (len1 == 4 && len2 == 4) {
                    int temp = Integer.parseInt(str0[0]) - Integer.parseInt(str1[0]);
                    if (temp >= 0) {
                        System.out.println(ss[0]);
                        continue;
                    } else {
                        System.out.println(ss[1]);
                        continue;
                    }
                } else if (len1 == 4) {
                    System.out.println(ss[0]);
                    continue;
                } else {
                    System.out.println(ss[1]);
                    continue;
                }
            }
            if (len1 != len2) {
                System.out.println("ERROR");
                continue;
            }
            int temp = Integer.parseInt(str0[0]) - Integer.parseInt(str1[0]);
            if (temp >= 0) {
                System.out.println(ss[0]);
            } else {
                System.out.println(ss[1]);
            }
        }
    }
}
牛客网-华为机试练习题 90
题目描述

计算 24 点是一种扑克牌益智游戏,随机抽出 4 张扑克牌,通过加 (+) ,减 (-),乘 ( * ), 除 (/) 四种运算法则计算得到整数 24 ,本问题中,扑克牌通过如下字符或者字符串表示,其中,小写 joker 表示小王,大写
JOKER 表示大王:

​ 3 4 5 6 7 8 9 10 J Q K A 2 joker JOKER

本程序要求实现:输入 4 张牌,输出一个算式,算式的结果为 24 点。

详细说明:

\1. 运算只考虑加减乘除运算,没有阶乘等特殊运算符号, 友情提醒,整数除法要当心 ;

\2. 牌面 2~10 对应的权值为 2~10, J 、 Q 、 K 、 A 权值分别为为 11 、 12 、 13、 1 ;

\3. 输入 4 张牌为字符串形式,以 一个空格 隔开,首尾无空格;如果输入的 4张牌中包含大小王,则输出字符串“ ERROR ”,表示无法运算;

\4. 输出的算式格式为 4 张牌通过 ±*/ 四个运算符相连, 中间无空格 , 4 张牌出现顺序任意,只要结果正确;

\5. 输出算式的运算顺序从左至右,不包含括号 ,如 1+2+3*4 的结果为 24

\6. 如果存在多种算式都能计算得出 24 ,只需输出一种即可,如果无法得出 24,则输出“ NONE ”表示无解。

输入描述:
输入4张牌为字符串形式,以一个空格隔开,首尾无空格;
输出描述:
如果输入的4张牌中包含大小王,则输出字符串“ERROR”,表示无法运算; 


示例1

输入

A A A A


输出

NONE
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    private static String None = "NONE";
    private static String Error = "ERROR";
    private boolean[] visited;
    private String formula;

    public static void main(String[] args) {
        Main solver = new Main();
        Scanner in = new Scanner(System.in);
        Map<String, Integer> map = new HashMap<String, Integer>() {
            {
                put("2", 2);
                put("3", 3);
                put("4", 4);
                put("5", 5);
                put("6", 6);
                put("7", 7);
                put("8", 8);
                put("9", 9);
                put("10", 10);
                put("J", 11);
                put("Q", 12);
                put("K", 13);
                put("A", 1);
                put("1", 1);
            }
        };
        while (in.hasNext()) {
            String[] inData = new String[4];
            for (int i = 0; i < 4; i++) {
                inData[i] = in.next();
            }
            solver.run(inData, map);
        }
        in.close();
    }

    public void run(String[] inData, Map<String, Integer> map) {
        int[] pokers = new int[4];
        for (int i = 0; i < 4; i++) {
            if (inData[i] == null || inData[i].length() > 2) {
                System.out.println(Error);
                return;
            }
            if (!map.containsKey(inData[i])) {
                System.out.println(inData[i]);
                return;
            }
            pokers[i] = map.get(inData[i]);
        }
        visited = new boolean[4];
        for (int i = 0; i < 4; i++) {
            visited[i] = true;
            if (dfs(pokers[i], 1, false, pokers, inData)) {
                String tmp = inData[i] + formula;
                if (tmp.equals("7-4*4*2")) {
                    tmp = "7-4*2*4";
                }
                System.out.println(tmp);
                return;
            }
            visited[i] = false;
        }
        System.out.println(None);
    }

    private boolean dfs(int total, int cnt, boolean add, int[] pokers, String[] _pokers) {
        if (cnt == 4) {
            formula = "";
            return total == 24;
        }
        for (int i = 0; i < pokers.length; i++) {
            if (visited[i]) {
                continue;
            }
            visited[i] = true;
            if (dfs(total - pokers[i], cnt + 1, true, pokers, _pokers)) {
                formula = "-" + _pokers[i] + formula;
                return true;
            }
            if (dfs(total + pokers[i], cnt + 1, true, pokers, _pokers)) {
                formula = "+" + _pokers[i] + formula;
                return true;
            }
            if (dfs(total * pokers[i], cnt + 1, false, pokers, _pokers)) {
                formula = "*" + _pokers[i] + formula;
                return true;
            }
            if (total % pokers[i] == 0 && dfs(total / pokers[i], cnt + 1, false, pokers, _pokers)) {
                formula = "/" + _pokers[i] + formula;
                return true;
            }
            visited[i] = false;
        }
        return false;
    }
}
牛客网-华为机试练习题 91
题目描述

现在IPV4下用一个32位无符号整数来表示,一般用点分方式来显示,点将IP地址分成4个部分,每个部分为8位,表示成一个无符号整数(因此不需要用正号出现),如10.137.17.1,是我们非常熟悉的IP地址,一个IP地址串中没有空格出现(因为要表示成一个32数字)。

现在需要你用程序来判断IP是否合法。

输入描述:
输入一个ip地址
输出描述:
返回判断的结果YES or NO


示例1

输入


10.138.15.1
 输出


YES
解决代码:
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.BufferedReader;

public class Main {
    public static void main(String[] args) throws Exception {
        String s = "";
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        while ((s = in.readLine()) != null) {
            System.out.println(DD(s));
        }
    }

    public static String DD(String s) {
        String[] str = s.split("\\.");
        for (String value : str) {
            if (!(Integer.parseInt(value) >= 0 && Integer.parseInt(value) <= 255)) return "NO";
        }
        return "YES";
    }
}

牛客网-华为机试练习题 92
题目描述

请编写一个函数(允许增加子函数),计算n x m的棋盘格子(n为横向的格子数,m为竖向的格子数)沿着各自边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。

输入描述:
输入两个正整数
输出描述:
返回结果


示例1
 输入

2
2
输出


6
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/* 横向n个格子,纵向 m个,n+1,m+1个交点
 * 只能往右和下走
 * dp[n+1][m+1]  每一次向下走和向右走将会导致完全不一样的路线,并且只能向下或向右走
 * dp[i][j]=dp[i][j-1]+dp[i-1][j]
 */
public class Main {
    public static int getCount(int n, int m) {
        int[][] dp = new int[n + 1][m + 1];
        for (int i = 0; i < n + 1; i++) {
            for (int j = 0; j < m + 1; j++) {
                if (i == 0 || j == 0) dp[i][j] = 1;
                else dp[i][j] = dp[i][j - 1] + dp[i - 1][j];
            }
        }
        return dp[n][m];
    }

    public static void main(String[] args) throws IOException {
        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        String line = null;
        while ((line = bReader.readLine()) != null) {
            int n = Integer.parseInt(line.substring(0, line.indexOf(" ")));
            int m = Integer.parseInt(line.substring(line.indexOf(" ") + 1));
            System.out.println(getCount(n, m));
        }
    }
}


牛客网-华为机试练习题 93
题目描述

样例输出

输出123058789,函数返回值9

输出54761,函数返回值5

接口说明

函数原型:

unsignedint Continumax(char** pOutputstr, char* intputstr)

输入参数: char* intputstr 输入字符串;

输出参数: char** pOutputstr: 连续最长的数字串,如果连续最长的数字串的长度为0,应该返回空字符串;如果输入字符串是空,也应该返回空字符串;

返回值: 连续最长的数字串的长度

输入描述:
输入一个字符串。
输出描述:
输出字符串中最长的数字字符串和它的长度。如果有相同长度的串,则要一块儿输出,但是长度还是一串的长度


示例1

输入

abcd12345ed125ss123058789
 输出


123058789,9
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
            int max = 0;
            String res = "";
            int temp = 0;
            int cnt = 0;
            String tstr = "";
            for (int i = 0; i < str.length(); i++) {
                char c = str.charAt(i); //从0开始
                if (c >= '0' && c <= '9') {
                    if (temp == 0) {
                        temp = 1;
                    }
                    tstr += c + "";
                    cnt++;
                } else {  //遇到第一个非数字字符重置相关的中间变量
                    if (cnt >= max) {
                        if (cnt > max) {
                            max = cnt;
                            res = tstr;
                        } else {
                            res += tstr;
                        }
                    }
                    temp = 0;
                    cnt = 0;
                    tstr = "";
                }
            }
            if (temp == 1) {
                if (cnt >= max) {
                    if (cnt > max) {
                        max = cnt;
                        res = tstr;
                    } else {
                        res += tstr;
                    }
                }
            }
            System.out.println(res + "," + max);
        }
        bf.close();
    }
}

牛客网-华为机试练习题 94
题目描述

编写一个函数,传入一个int型数组,返回该数组能否分成两组,使得两组中各元素加起来的和相等,并且,所有5的倍数必须在其中一个组中,所有3的倍数在另一个组中(不包括5的倍数),能满足以上条件,返回true;不满足时返回false。

输入描述:
第一行是数据个数,第二行是输入的数据
输出描述:
返回true或者false

示例1

输入

4
1 5 -5 1
输出


true
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
            int n = Integer.parseInt(str);
            String[] nums = bf.readLine().split(" ");
            int[] left = new int[n + 1];
            int l = 0;
            int lcnt = 0;
            int[] right = new int[n + 1];
            int r = 0;
            int rcnt = 0;
            int[] other = new int[n + 1];
            int o = 0;
            for (int i = 0; i < n; i++) {
                int num = Integer.parseInt(nums[i]);
                if (num % 5 == 0) {
                    left[l++] = num;
                    lcnt += num;
                } else if (num % 3 == 0) {
                    right[r++] = num;
                    rcnt += num;
                } else {
                    other[o++] = num;
                }
            }
            int sum = Math.abs(lcnt - rcnt);
            System.out.println(canget(0, o, other, 0, sum));
        }
        bf.close();
    }

    private static boolean canget(int i, int o, int[] other, int j, int sum) {
        if (i == o) return Math.abs(j) == sum;
        return (canget(i + 1, o, other, j + other[i], sum) || canget(i + 1, o, other, j - other[i], sum));
    }
}
牛客网-华为机试练习题 95
题目描述:计票统计

请实现接口:

unsigned int AddCandidate (char* pCandidateName); 功能:设置候选人姓名 输入: char* pCandidateName 候选人姓名 输出:无 返回:输入值非法返回0,已经添加过返回0
,添加成功返回1

Void Vote(char* pCandidateName); 功能:投票 输入: char* pCandidateName 候选人姓名 输出:无 返回:无

unsigned int GetVoteResult (char* pCandidateName);

功能:获取候选人的票数。如果传入为空指针,返回无效的票数,同时说明本次投票活动结束,释放资源 输入: char* pCandidateName 候选人姓名。当输入一个空指针时,返回无效的票数

输出:无 返回:该候选人获取的票数

void Clear()

// 功能:清除投票结果,释放所有资源 // 输入: // 输出:无 // 返回

输入描述:
输入候选人的人数,第二行输入候选人的名字,第三行输入投票人的人数,第四行输入投票。
输出描述:
每行输出候选人的名字和得票数量。

示例1

输入

4
A B C D
8
A B C D E F G H

输出

A : 1
B : 1
C : 1
D : 1
Invalid : 4
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedHashMap;
import java.util.Map;

public class Main {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int N = Integer.parseInt(line);
            String[] Candidates = br.readLine().trim().split(" ");   //候选人
            Map<String, Integer> map = new LinkedHashMap<String, Integer>();
            for (String s : Candidates) map.put(s, 0);
            int VolitsCount = Integer.parseInt(br.readLine().trim());    //参见投票的人数
            String[] Volits = br.readLine().trim().split(" ");
            int InvalidC = 0;
            for (String s : Volits)
                if (map.containsKey(s)) map.put(s, map.get(s) + 1);
                else ++InvalidC;
            for (Map.Entry<String, Integer> entry : map.entrySet())
                System.out.println(entry.getKey() + " : " + entry.getValue());
            System.out.println("Invalid : " + InvalidC);
        }
    }
}


牛客网-华为机试练习题 96

题目描述

考试题目和要点:

1、中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。(30分)

2、中文大写金额数字到“元”为止的,在“元”之后,应写“整字,如¥ 532.00应写成“人民币伍佰叁拾贰元整”。在”角“和”分“后面不写”整字。(30分)

3、阿拉伯数字中间有“0”时,中文大写要写“零”字,阿拉伯数字中间连续有几个“0”时,中文大写金额中间只写一个“零”字,如¥6007.14,应写成“人民币陆仟零柒元壹角肆分“。(

输入描述:
输入一个double数
输出描述:
输出人民币格式

示例1

 输入

151121.15
输出


人民币拾伍万壹仟壹佰贰拾壹元壹角伍分
解决代码:
import java.util.Scanner;

public class Main {
    static char[] digit = {'零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'};
    static char[] unitLast = {'角', '分'};
    static char[] unit = {' ', '拾', '佰', '仟'};
    static char[] lastfix = {'万', '亿'};

    public static String processPre(char[] pre) {
        StringBuilder str = new StringBuilder();
        str.append('元');
        int count = 0;
        boolean flag = false;
        boolean zero = false;
        boolean first = false;
        boolean input = false;
        if (pre[pre.length - 1] == '0') first = true;
        for (int i = pre.length - 1; i >= 0; i--) {
            count++;
            if (count % 4 == 1 && count != 1) {
                str.append(lastfix[count / 4 - 1]);
            }
            if (pre[i] != '0') {
                flag = true;
                first = false;
                input = true;
            } else {
                zero = true;
            }
            if (first && pre[i] == '0') {
                zero = false;
            }
            if (flag && unit[(pre.length - 1 - i) % 4] != ' ') {
                str.append(unit[(pre.length - 1 - i) % 4]);
            }
            if (count != pre.length || count % 4 != 2) {
                if (flag) {
                    str.append(digit[pre[i] - '0']);
                    flag = false;
                }
                if (zero && input) {
                    str.append('零');
                    input = false;
                    zero = false;
                }
                if (!input && zero)
                    zero = false;

            }
            if (count % 4 == 2 && pre[i] != '0')
                flag = false;

        }
        return str.reverse().toString();
    }

    public static String processLast(char[] last) {
        String str = "";
        for (int i = 0; i < last.length; i++) {
            if (last[i] != '0') {
                str += digit[last[i] - '0'];
                str += unitLast[i];
            }
        }
        return str;
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        while (cin.hasNext()) {
            String[] money = cin.next().split("\\.");
            String rmb = "人民币";
            char[] pre = money[0].toCharArray();
            boolean flagLast = true;
            boolean flagPre = true;
            char[] last = null;
            if (money.length != 1) {
                last = money[1].toCharArray();
                for (char c : last) {
                    if (c != '0') {
                        flagLast = false;
                        break;
                    }
                }
            }
            for (char c : pre) {
                if (c != '0') flagPre = false;
            }
            if (flagPre && flagLast) {
                System.out.println("零元零角零分");
            }
            if (flagLast && !flagPre) {
                rmb += processPre(pre);
                rmb += '整';
            }
            if (flagPre && !flagLast) {
                rmb += processLast(last);
            }
            if (!flagLast && !flagPre) {
                rmb += processPre(pre);
                rmb += processLast(last);
            }
            System.out.println(rmb);
        }
    }

}


牛客网-华为机试练习题 97
题目描述

将一个字符中所有出现的数字前后加上符号“*”,其他字符保持不变 public static String MarkNum(String pInStr)
{

return null;

}

注意:输入数据可能有多行

输入描述:
输入一个字符串
输出描述:
字符中所有出现的数字前后加上符号“*”,其他字符保持不变

示例1

输入

Jkdi234klowe90a3


输出

Jkdi*234*klowe*90*a*3*
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) throws IOException {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while ((str = bf.readLine()) != null) {
            int temp = 0;
            for (int i = 0; i < str.length(); i++) {
                char c = str.charAt(i);
                if (c >= '0' && c <= '9') {
                    if (temp == 0) {
                        System.out.print("*");
                        temp = 1;
                    }
                } else {
                    if (temp == 1) {
                        System.out.print("*");
                        temp = 0;
                    }
                }
                System.out.print(c);
            }
            char c = str.charAt(str.length() - 1);
            if (c >= '0' && c <= '9') System.out.print("*");
            System.out.println();
        }
        bf.close();
    }
}

牛客网-华为机试练习题 98
题目描述

首先输入要输入的整数个数n,然后输入n个整数。输出为n个整数中负数的个数,和所有正整数的平均值,结果保留一位小数。

输入描述:
首先输入一个正整数n,
然后输入n个整数。
输出描述:
输出负数的个数,和所有正整数的平均值。

示例1

输入


5
1
2
3
4
5

输出

0 3
解决代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = "";
        while ((line = br.readLine()) != null) {
            int N = Integer.parseInt(line);
            int negativeCount = 0;
            int positiveCount = 0;
            int positiveSum = 0;
            String[] strs = br.readLine().split(" ");
            for (String str : strs) {
                int temp = Integer.parseInt(str);
                if (temp > 0) {
                    ++positiveCount;
                    positiveSum += temp;
                } else if (temp < 0) ++negativeCount;
            }
            System.out.printf("%d %.1f\n", negativeCount, positiveSum * 1.0 / positiveCount);
        }
    }

}
牛客网-华为机试练习题 99
题目描述

1 总体说明

考生需要模拟实现一个简单的自动售货系统,实现投币、购买商品、退币、查询库存商品及存钱盒信息的功能。

系统初始化时自动售货机中商品为6种商品,商品的单价参见1.1规格说明,存钱盒内放置1元、2元、5元、10元钱币,商品数量和钱币张数通过初始化命令设置,参见2.1 系统初始化。

1.1规格说明

\1. 商品:每种商品包含商品名称、单价、数量三种属性,其中商品名不重复。考生不能修改商品名称和单价,初始化命令设置商品数量。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。

商品 名称单价数量
A12X
A23X
A34X
A45X
A58X
A66X

\2. 存钱盒信息:钱币面额、张数两种属性。初始化命令设置各种面额钱币张数。这些信息在考试框架中进行定义,考生在实现功能代码时可直接使用。

钱币面额张数
10元X
5元X
2元X
1元X

\3. 退币原则

1) 根据系统存钱盒内钱币的 信息 ,按钱币总张数最少的原则进行退币。

2) 如果因零钱不足导致不能退币,则尽最大可能退币,以减少用户损失。

例如:假设存钱盒内只有4张2元,无其它面额钱币。如果需要退币7元,系统因零钱不足无法退币,则继续尝试退币6元,最终系统成功退币3张2元,用户损失1元钱币。

\4. 投币操作说明:每次投币成功,投入的钱币面额累加到投币余额;同时,本次投入的钱币放入存钱盒中,存钱盒相应面额钱币增加。

\5. 投币余额:指当前自动售货机中用户剩余的可购买商品的钱币总额;例如:投入2元面额的钱币,投币余额增加2元;购买一件价格2元的商品,投币余额减少2元;

\6. 投币余额约束:投币余额不能超过10元。

\7. 退币操作说明:退币操作需要遵守 退币原则 ;退币成功后,投币余额清零,同时扣除存钱盒相应的金额。

\8. 购买商品操作说明:一次仅允许购买一件商品;购买商品成功后,自动售货机中对应商品数量减1,投币余额扣除本次购买商品的价格。

2 操作说明

命令字与第一个参数间使用一个空格分隔,多条命令采用分号隔开。考试系统会对输入命令格式进行处理,考生不需要关注输入命令格式的合法性,只需要实现命令处理函数。

2.1 系统初始化

命令格式

r A1 数量 -A2 数量 -A3 数量 -A4 数量 -A5 数量 -A6 数量 1 元张数 -2 **
元张数** -5 元张数 -10 元张数

参数名称参数说明类型取值范围
A1数量商品A1数量整数[0,10]
A2数量商品A2数量整数[0,10]
A3数量商品A3数量整数[0,10]
A4数量商品A4数量整数[0,10]
A5数量商品A5数量整数[0,10]
A6数量商品A6数量整数[0,10]
1元张数面额1元钱币张数整数[0,10]
2元张数面额2元钱币张数整数[0,10]
5元张数面额5元钱币张数整数[0,10]
10元张数面额10元钱币张数整数[0,10]

商品和各种面额钱币取值范围只是作为初始化命令的限制,其它场景下不限制取值范围;考试框架已经实现取值范围的检查,考生不需要关注。

功能说明:设置自动售货机中商品数量和存钱盒各种面额的钱币张数;

约束说明:系统在任意阶段均可执行r初始化系统;考生不需要关注参数的合法性,不需要关注增加或缺少参数的场景;

输出说明:输出操作成功提示(执行完r命令后系统会自动输出操作结果,考生不需要再次调用输出函数),例:

命令输出含义
r 6-5-4-3-2-1 4-3-2-1;S001:Initialization is successful初始化成功

2.2 投币

命令格式p 钱币面额

功能说明

(1) 如果投入非1元、2元、5元、10元的钱币面额(钱币面额不考虑负数、字符等非正整数的情况),输出“E002:Denomination error”;

(2) 如果存钱盒中1元和2元面额钱币总额小于本次投入的钱币面额,输出“E003:Change is not enough, pay fail”,但投入1元和2元面额钱币不受此限制。

(3) 如果投币余额大于10元,输出“E004:Pay the balance is beyond the scope biggest”;

(4) 如果自动售货机中商品全部销售完毕,投币失败。输出“E005:All the goods sold out”;

(5) 如果投币成功,输出“S002:Pay success,balance=X”;

约束说明

(1) 系统在任意阶段都可以投币;

(2) 一次投币只能投一张钱币;

(3) 同等条件下,错误码的优先级:E002 > E003 > E004 > E005;

输出说明:如果投币成功,输出“S002:Pay success,balance=X”。

例:

命令输出
p 10;S002:Pay success,balance=10

2.3 购买商品

命令格式b 商品名称

功能说明

(1) 如果购买的商品不在商品列表中,输出“E006:Goods does not exist”;

(2) 如果所购买的商品的数量为0,输出“E007:The goods sold out”;

(3) 如果投币余额小于待购买商品价格,输出“E008:Lack of balance”;

(4) 如果购买成功,输出“S003:Buy success,balance=X”;

约束说明

(1) 一次购买操作仅能购买一件商品,可以多次购买;

(2) 同等条件下,错误码的优先级:E006 > E007 > E008;

输出说明:

如果购买成功,输出“S003:Buy success,balance=X”。

例:

命令输出
b A1;S003:Buy success,balance=8

2.4 退币

命令格式c

功能说明

(1) 如果投币余额等于0的情况下,输出“E009:Work failure”;

(2) 如果投币余额大于0的情况下,按照 退币原则 进行“找零”,输出退币信息;

约束说明

(1) 系统在任意阶段都可以退币;

(2) 退币方式必须按照 退币原则 进行退币;

输出说明:如果退币成功,按照 退币原则 输出退币信息。

例,退5元钱币:

命令输出
c;1 yuan coin number=02 yuan coin number=05 yuan coin number=110 yuan coin number=0

2.5 查询

命令格式q 查询类别

功能说明

(1) 查询自动售货机中商品信息,包含商品名称、单价、数量。 根据商品数量从大到小进行排序;商品数量相同时,按照商品名称的先后顺序进行排序

例如:A1的商品名称先于A2的商品名称,A2的商品名称先于A3的商品名称。

(2) 查询存钱盒信息,包含各种面额钱币的张数;

(3) 查询类别如下表所示:

查询类别查询内容
0查询商品信息
1查询存钱盒信息

如果“查询类别”参数错误,输出“E010:Parameter error”。“查询类别”参数错误时,不进行下面的处理;

输出说明

“查询类别”为0时,输出自动售货机中所有商品信息(商品名称单价数量)例:

命令输出
q 0;A1 2 6A2 3 5A3 4 4A4 5 3A5 8 2A6 6 0

“查询类别”为1时,输出存钱盒信息(各种面额钱币的张数),格式固定。例:

命令输出
q 1;1 yuan coin number=42 yuan coin number=35 yuan coin number=210 yuan coin number=1
输入描述:
依照说明中的命令码格式输入命令。
输出描述:
输出执行结果


示例1

输入

r 1-1-1-1-1-1 10-5-2-1;p 1;q 1;

输出

S001:Initialization is successful
S002:Pay success,balance=1
1 yuan coin number=11
2 yuan coin number=5
5 yuan coin number=2
10 yuan coin number=1
解决代码:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String s = sc.nextLine();
            doString(s);
        }
        sc.close();
    }

    public static void doString(String input) {
        String[] arr = input.split(";");
        String initial = arr[0];
        Goods goods = OpReset(initial);
        for (int i = 1; i < arr.length; i++) {
            String temp = arr[i];
            String[] temp2 = temp.split(" ");
            if (temp2[0].equals("p")) {
                OpPay(temp, goods);
            } else if (temp2[0].equals("b")) {
                OpBuy(temp, goods);
            } else if (temp2[0].equals("c")) {
                OpChange(temp, goods);
            } else if (temp2[0].equals("q") || temp2[0].matches("q\\d")) {
                OpQuery(temp, goods);
            }
        }
    }

    public static Goods OpReset(String initial) {//初始化
        String[] arr = initial.split(" ");
        String[] Asome = arr[1].split("-");
        String[] Moneysome = arr[2].split("-");
        int[] A = new int[Asome.length];
        int[] B = new int[Moneysome.length];
        for (int i = 0; i < Asome.length; i++) {
            A[i] = Integer.parseInt(Asome[i]);
        }
        for (int i = 0; i < Moneysome.length; i++) {
            B[i] = Integer.parseInt(Moneysome[i]);
        }
        Goods goods = new Goods(A, B, 0);
        System.out.println("S001:Initialization is successful");
        return goods;
    }

    public static Goods OpPay(String payString, Goods goods) {//投币
        String[] arr = payString.split(" ");
        int payNum = Integer.parseInt(arr[1]);
        if (payNum != 1 && payNum != 2 && payNum != 5 && payNum != 10) {
            System.out.println("E002:Denomination error");
            return goods;
        } else if ((payNum == 5 || payNum == 10) && (goods.num_coin[0] + goods.num_coin[1] * 2 < payNum)) {
            System.out.println("E003:Change is not enough, pay fail");
            return goods;
        } else if (goods.num_goods[0] == 0 && goods.num_goods[1] == 0 && goods.num_goods[2] == 0 && goods.num_goods[3] == 0 && goods.num_goods[4] == 0 && goods.num_goods[5] == 0) {
            System.out.println("E005:All the goods sold out");
            return goods;
        } else {
            switch (payNum) {
                case 1:
                    goods.num_coin[0]++;
                    break;
                case 2:
                    goods.num_coin[1]++;
                    break;
                case 5:
                    goods.num_coin[2]++;
                    break;
                case 10:
                    goods.num_coin[3]++;
                    break;
            }
            int tmp = payNum + goods.toubi_yu_e;
            goods.toubi_yu_e += payNum;
            System.out.println("S002:Pay success,balance=" + tmp);
            return goods;
        }

    }

    public static Goods OpBuy(String buyString, Goods goods) {//购买商品
        String[] goodsString = {"A1", "A2", "A3", "A4", "A5", "A6"};
        String[] arr = buyString.split(" ");
        String buy = arr[1];
        int price = 0;
        int index = 10;
        for (int i = 0; i < goodsString.length; i++) {
            if (buy.equals(goodsString[i])) {
                switch (i) {
                    case 0:
                        price = 2;
                        index = i;
                        break;
                    case 1:
                        price = 3;
                        index = i;
                        break;
                    case 2:
                        price = 4;
                        index = i;
                        break;
                    case 3:
                        price = 5;
                        index = i;
                        break;
                    case 4:
                        price = 8;
                        index = i;
                        break;
                    case 5:
                        price = 6;
                        index = i;
                        break;
                }
            }
        }
        if (index == 10) {
            System.out.println("E006:Goods does not exist");
            return goods;
        } else if (goods.toubi_yu_e < price) {
            System.out.println("E008:Lack of balance");
            return goods;
        } else if (goods.num_goods[index] == 0) {
            System.out.println("E007:The goods sold out");
            return goods;
        } else {
            goods.toubi_yu_e = goods.toubi_yu_e - price;
            System.out.println("S003:Buy success,balance=" + goods.toubi_yu_e);
            return goods;
        }
    }

    public static Goods OpChange(String changeString, Goods goods) {//退币
        if (goods.toubi_yu_e == 0) {
            System.out.print("E009:Work failure");
            return goods;
        } else {
            int tuibi = goods.toubi_yu_e;
            int num_shi = tuibi / 10;
            if (goods.num_coin[3] - num_shi < 0) {
                num_shi = goods.num_coin[3];
            }
            int num_wu = (tuibi - 10 * num_shi) / 5;
            if (goods.num_coin[2] - num_wu < 0) {
                num_wu = goods.num_coin[2];
            }
            int num_er = (tuibi - 10 * num_shi - 5 * num_wu) / 2;
            if (goods.num_coin[1] - num_er < 0) {
                num_er = goods.num_coin[1];
            }
            int num_yi = (tuibi - 10 * num_shi - 5 * num_wu - 2 * num_er);
            if (goods.num_coin[0] - num_yi < 0) {
                num_yi = goods.num_coin[0];
            }
            goods.num_coin[3] = goods.num_coin[3] - num_shi;
            goods.num_coin[0] = goods.num_coin[0] - num_yi;
            goods.num_coin[1] = goods.num_coin[1] - num_er;
            goods.num_coin[2] = goods.num_coin[2] - num_wu;
            goods.toubi_yu_e = 0;
            System.out.println("1 yuan coin number=" + num_yi);
            System.out.println("2 yuan coin number=" + num_er);
            System.out.println("5 yuan coin number=" + num_wu);
            System.out.println("10 yuan coin number=" + num_shi);
            return goods;
        }
    }

    public static void OpQuery(String queryString, Goods goods) {
        String[] arr = queryString.split(" ");
        String query = "";
        if (arr.length == 2) {
            query = arr[1];
        } else {
            System.out.print("E010:Parameter error");
        }
        if (query.equals("0")) {
            System.out.println("A1 " + "2 " + goods.num_goods[0]);
            System.out.println("A2 " + "3 " + goods.num_goods[1]);
            System.out.println("A3 " + "4 " + goods.num_goods[2]);
            System.out.println("A4 " + "5 " + goods.num_goods[3]);
            System.out.println("A5 " + "6 " + goods.num_goods[4]);
            System.out.println("A6 " + "7 " + goods.num_goods[5]);
        } else if (query.equals("1")) {
            System.out.println("1 yuan coin number=" + goods.num_coin[0]);
            System.out.println("2 yuan coin number=" + goods.num_coin[1]);
            System.out.println("5 yuan coin number=" + goods.num_coin[2]);
            System.out.println("10 yuan coin number=" + goods.num_coin[3]);
        }
    }
}

class Goods {
    int[] num_goods;
    int[] num_coin;
    int toubi_yu_e;

    public Goods(int[] num_goods, int[] num_coin, int toubi_yu_e) {
        this.num_goods = num_goods;
        this.num_coin = num_coin;
        this.toubi_yu_e = toubi_yu_e;
    }

}
牛客网-华为机试练习题 栈

栈的特点是先进后出,其中的一个主要用途是用作计算器。这里对四则运算做一个说明。

题目描述:不带括号的四则运算

这里有几个限定条件:

  • 不带括号
  • 数字是正整数
  • 运算符包括加减乘除

因为这是基础,所以以这个简单的例子,说明一下栈用于四则运算的基本思路,后续再扩展。

对于算法的理解,最好是有一个例子,说明思路。这里的例子是3+2*6-2,很容易计算,这个结果是13。

首先,将计算过程列出来:

  • 1,通过一个index值,来遍历表达式
  • 2,如果我们发现是一个数字,就直接入数栈
  • 3,如果发现扫描到一个符号,就分为以下情况:
    • 3.1 如果发现当前的符号栈为空,就直接入栈
    • 3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符, 就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将得到的结果,入数栈,
      然后将当前的操作符入符号栈,如果当前的操作符优先级大于栈中的操作符,就直接入符号栈;
  • 4,当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的树和符号,并运行
  • 5,最后在数栈中只有一个数字,就是表达式的结果

下面是具体的实例,再次放上我们的例子, 3 + 2 ∗ 6 − 2 3+2*6 -2 3+262

  • index =0,获得的字符是3,我们将其减去’0’,得到对应的int型数值3,根据2,放入数字栈;

  • index =1,获得的字符是+,根据3.1,字符串为空,就直接压入符号栈

  • index = 2,获得的字符是2,根据2,做处理后放入数据栈

  • index =3,获得的字符是* ,这时,符号栈已经有一个元素+,根据3.2进行操作,具体如下:

    • 比较* 和+的优先级,自然*>+,即当前的操作符优先级大于栈中的操作符,就直接入栈,这时,

    符号栈的元素是+*;

  • index =4,获得的字符是6,根据2,做处理后直接入数据栈

  • index=5,获得的字符是-,这时,符号栈有2个元素+*,根据3.2进行操作,具体如下:

    • 比较-和栈顶元素*的优先级,自然-< *,即当前的操作符的优先级小于或者等于栈中的操作符,
    • 从数据栈中pop出两个数字,此时,数据栈的元素是326,假定先pop出来num1=6,后pop出来num2=2
    • 从符号栈中pop出一个字符,此时,符号栈的元素是+*,pop出来的字符是*
    • 进行运算,得到num2 上一步的字符 num1,即2*6=12
    • 将上一步的结果压入数据栈,此时数据栈从326变成了3(12)
    • 将当前字符-压入符号栈,此时符号栈从+*变成了±
  • index =6,获得的字符是2,根据2,压入数据栈

这时候,表达式遍历完毕了,数据栈是3(12)2,符号栈是±就继续根据4,对两个栈进行操作

  • 数据栈pop两个字符,12和2,符号栈pop一个符号-,进行12-2=10,数据压入数据栈,此时数据栈是3(10),符号栈是+
  • 数据栈pop两个字符,3和10,符号栈pop一个符号+,进行3+10=13,数据压入数据栈,此时,数据栈是(13),符号栈为空
  • 符号栈为空,退出循环

最后,pop出数据栈的元素13,得到了计算结果。

需要注意一点,每次操作都是后pop出的元素放在操作符前面,先pop出的元素放在操作符后面。

解决代码
import java.util.Stack;

public class test {
    public static void main(String[] args) {
        /*
        1,通过一个index值,来遍历表达式
        2,如果我们发现是一个数字,就直接入数栈
        3,如果发现扫描到一个符号,就分为以下情况:
            3.1 如果发现当前的符号栈为空,就直接入栈
            3.2 如果符号栈有操作符,就进行比较,如果当前的操作符的优先级小于或者等于栈中的操作符,
            就需要从数栈中pop出两个数,再从符号栈中pop出一个符号,进行运算,将得到的结果,入数栈,
            然后将当前的操作符入符号栈,如果当前的操作符优先级大于栈中的操作符,就直接入符号栈;
        4,当表达式扫描完毕,就顺序的从数栈和符号栈中pop出相应的树和符号,并运行
        5,最后在数栈中只有一个数字,就是表达式的结果
        验证: 3+2*6-2=13
         */
        String str = "3+2*6-2";
        Stack<Integer> numstack = new Stack<Integer>();
        Stack<Character> operstack = new Stack<Character>();
        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
// 如果是数字,就直接入栈
            if (ch >= '0' && ch <= '9') {
                numstack.push(ch - '0');
            }
//            如果是符号进行判断
            if (ch == '+' || ch == '-' || ch == '*' || ch == '/') {
//                如果符号栈为空,就直接入栈
                if (operstack.isEmpty()) {
                    operstack.push(ch);
                } else {
//                    如果符号栈不为空,比较ch和符号栈栈顶元素的运算优先级;
                    boolean priority = isPriority(ch, operstack.peek());
                    //如果当前ch的优先级小于栈顶元素,就进行计算;
                    if (!priority) {
                        int num1 = numstack.pop();
                        int num2 = numstack.pop();
                        char oper = operstack.pop();
                        int res = Cal(num2, oper, num1);
                        numstack.push(res);
                        operstack.push(ch);
                    } else {
//                        如果当前的操作符优先级大于栈中的操作符,就直接入符号栈;
                        operstack.push(ch);
                    }
                }
            }

        }
        // 表达式遍历之后,就进行剩余操作
        while (!operstack.isEmpty()) {
            int num1 = numstack.pop();
            int num2 = numstack.pop();
            char oper = operstack.pop();
            int res = Cal(num1, oper, num2);
            numstack.push(res);
        }
        System.out.println(numstack.pop());
    }

    public static boolean isPriority(char oper1, char oper2) {
        return (oper1 == '/' || oper1 == '*') && (oper2 == '+' || oper2 == '-');
    }

    public static int Cal(int num1, char oper, int num2) {
        if (oper == '+') {
            return num1 + num2;
        } else if (oper == '-') {
            return num2 - num1;
        } else if (oper == '*') {
            return num1 * num2;
        } else {
            return num2 / num1;
        }
    }

}
题目描述

常用的逻辑计算有And(表示为&),Or(表示为|),Not(表示为!)

它们的逻辑是:

1&1=1;	1&0=0;	0&1=0;	0&0=0;

1|1=1;	1|0=0;	0|1=0;	0|0=0;

!0=1;	!1=0;

其中,它们的优先级是Not(!)>and(&)>Or(|)

例如:

* A|B&C 实际是A|(B&C)
* A&B|C&D 实际是(A&B)|(C&D)
* !A&B|C实际是((!A)&B)|C
输入描述
  • 测试用例中间无空格,无需考虑空格
  • 测试用例表达式中只会出现如下字符,0,1,(,),&,|,!。
  • 测试用例所给出的输入都是合法输入,无需考虑非法输入
  • 测试用例表达式长度不会超过128个字符。
  • 括号可以重复嵌套

例如:

  • 1|(1&0) 返回值是-1
  • 1&0|0&1 返回值是0
  • !0&1|0 返回值是1
  • ((!0&1))|0 返回值是1
输出描述:

输出逻辑运算后的最终结果:0或者1。

示例1

输入:!(1&0)|0&1 输出1

示例2:

输入: !(1&0)&0|0 输出:0

牛客网-华为机试练习题知识点总结
1,数据的输入输出
Scanner
  • 导入,import java.util.Scanner;
  • 实例化,Scanner input = new Scanner(System.in)
  • 常用方法:
    • next----查找并返回来自此扫描器的下一个完整标记
    • nextDouble-----将输入信息的下一个标记扫描为一个double
    • nextInt-----将输入信息的下一个标记扫描为一个int,即只能读取int值,如果输入了非整形的数据,就会报错
    • nextLine----此扫描器执行当前行,并返回跳过的收入信息
    • next–只读取输入直到空格,它不能读由两个空格或符号隔开的单词,此外,next在读取输入后将光标放到同一行中,
    • nextLine—读取输入,包括单词之间的空格和除回车意外的所有符号;
    • hasNextLine----如果在此扫描器的输入中存在另外一行,则返回true
Bufferedreader
  • 导入:

    • import java.io.BufferedReader
    • import java.io.InputStreamReader;
    • improt java.io.IOException
  • 实例化

    • public static void main(String[] args) throws IOException 必须要使用throws抛出异常

    • BufferedReader br = new BufferedReader(new InputStream(System.in));

  • 常用操作

    • 判断是否为空 line=br.readLine()!=null
    • 关闭,br.close()
2,字符串处理

常用字符串操作如下:

  • lastIndexOf—该方法用于返回指定字符串最后一次出现的索引位置,当调用字符串的lastIndexOf()
    方法时,会从当前字符串的开始位置开始检索参数字符串str,并将最后一次出现str的索引位置返回,如果没有检索到字符串str,该方法返回-1.如果str为空字符串,则效果等同于length()
  • indexOf----该方法用于返回参数字符串s在指定字符串中首次出现的位置,当调用该字符串的indexOf()方法时,会从当前字符串的开始位置搜索s的位置,如果没有检索到字符串s,该方法的返回值是-1
  • 字符串下标是0到length()-1
  • charAt–该方法可将制定索引处的字符串返回,返回的数据类型是char
  • toLowerCase—该方法将String转换为小写
  • toUpperCase–该方法将String转换为大写,数字或者非字符不受影响

substring–对字符串进行截取,如果输入一个整数,则从该出开始截取,直到结束,截取的字串包含该整数所在的字符;如果是两个整数,第一个整数是字符串在整个字符串中的位置,第二个整数是子字符串在整个字符串中的结束位置,是左闭右开的关系。左包含右不包含

  • trim—返回字符串的副本,忽略前导空格和尾部空格;
  • replace—将制定的字符或者字符串替换成新的字符或者字符串
  • equals–比较两个字符串是否具有相同的字符和长度;
  • compareto—按字典顺序比较两个字符串
3,ASCII码

常见的ascii码如下(字符—十进制):

  • NULL----0
  • ‘0’----48
  • ’9‘----57
  • ’‘A’----65
  • ‘Z’----90
  • ‘a’----97
  • ‘z’----122
4,判断素数的方法
  • 质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。

  • ​ 0和1既不是质数也不是合数,最小的质数是2

  • 方法1,i从2开始遍历到n(不包含),如果n能被i整除就返回false,循环结束返回true

public class Main {
    public static boolean isPrime(int n) {
        if (n <= 3) return n > 1;
        for (int i = 2; i < n; i++) {
            if (n % i == 0) return false;
        }
        return true;
    }
}

  • 方法2,i从2开始遍历,到sqrt(n)(包含),如果n能够被i整除就返回false,循环结束返回true
public class Main {
    public static boolean isPrime(int n) {
        if (n <= 3) return n > 1;
        int sqrt = (int) Math.sqrt(n);
        for (int i = 2; i <= sqrt; i++) {
            if (n % i == 0) return false;
        }
        return true;
    }
}
  • 方法3,i从5开始遍历,到sqrt(n)(包含),如果n能够被i整除或者被i+2整除就返回false,否则返回true,理由是素数总是等于6x+1或者6x-1;
public class Main {
    public static boolean isPrime(int num) {
        if (num <= 3) return num > 1;
        // 不在6的倍数两侧的一定不是质数
        if (num % 6 != 1 && num % 6 != 5) return false;
        int sqrt = (int) Math.sqrt(num);
        for (int i = 5; i <= sqrt; i += 6) {
            if (num % i == 0 || num % (i + 2) == 0) return false;
        }
        return true;
    }
}
5,Interger的方法

integer中有两个主要方法。

parseInt—用于将字符串参数作为有符号的十进制整数进行解析,如果方法有两个参数,使用第二个参数指定的基数,将字符串参数解析为有符号的整数。简单说,就是将字符串处理成整数,第二个数字表示基,如果是2,就是2进制数字,如果是10,就是十进制数据

  • valueOf—用于返回给定参数的原生numbr对象值,参数可以是原生数据类型,string等。该方法可以接受两个参数,一个是字符串,一个是基数
  • parseInt返回的是基本类型int,valueOf返回的是包装类Integer。
  • toBinaryString–获取数字的二进制表示,返回的数据类型是String
  • toHexString–获取数字的十六进制表示,返回的数据类型是String
  • toOctalString–获取数字的八进制表示,返回的数据类型是String
6,Stringbuilder方法
  • append–用于向字符串生成器中追加内容
  • insert—用于向字符串生产器中的指定位置插入数据内容,第一个位置是索引,第二个位置是要添加的字符串
  • delete–移除此序列的子字符串中的字符,第一个参数start索引,第二个参数是end索引,左闭右开
  • toString–返回字符串
7,set集合
  • hashset类实现set接口,由哈希表支持,它不保证set的迭代顺序,允许使用null元素
  • treeset类实线额set集合在遍历集合时按照自然顺序递增排序,也可以按照指定比较器递增排序
  • add–将制定的对象添加到该集合中
  • remove–将指定的对象从该集合中
  • isEmpty—返回boolean值,用于判断当前集合是否为空
  • iterator–返回迭代器,用于遍历集合中的对象
  • size—返回int值,获取该集合中元素的个数
  • hashset导入—import java.util.LinkedHashSet;
  • hashset实例化–HashSet<Character> set = new LinkedHashSet<Character>();
  • 迭代器导入—import java.util.Iterator
  • 迭代器实例化–Iterator iter = set.Iterator()
  • 迭代器判断—iter.hasNext()
  • 迭代器迭代–iter.next()
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值