1、HJ15 输入一个int型的正整数,计算出该int型数据在内存中存储时1的个数
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
String b = Integer.toBinaryString(n);
int count = 0;
for(int i=0;i<b.length();i++){
if(b.charAt(i)=='1') {
count++;
}
}
System.out.println(count);
}
}
我的方法比较基础,学习一下别人有趣的方法。位运算:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int count = 0;
while(n>0){
if((n&1)>0){
count++;
}
n=n>>1;
}
System.out.println(count);
}
}
2、HJ50 输入一个表达式(用字符串表示),求这个表达式的值。保证字符串中的有效字符包括[‘0’-‘9’],‘+’,‘-’, ‘*’,‘/’ ,‘(’, ‘)’,‘[’, ‘]’,‘{’ ,‘}’。且表达式一定合法。
这道题我想到了用两个栈来解决,但是没想明白具体方法,直接来看参考题解。
import java.util.*;
public class Main{
// 用于存放一个正括号的集合, 用于简化代码
static Set<Character> brace = new HashSet<>();
public static void main(String ... args){
Scanner sc = new Scanner(System.in);
// 初始化正括号集合
brace.add('{');
brace.add('(');
brace.add('[');
while(sc.hasNextLine()){
// 对字符串做初始化处理,原则有二:
// 1、处理负数,这里在-前面的位置加入一个0,如-4变为0-4,
// 细节:注意-开头的地方前面一定不能是数字或者反括号,如9-0,(3-4)-5,这里地方是不能加0的
// 它的后面可以是数字或者正括号,如-9=>0-9, -(3*3)=>0-(3*3)
// 2、处理字符串,在最后的位置加#, 主要是为了防止最后一个整数无法处理的问题
String exp = sc.nextLine().replaceAll("(?<![0-9)}\\]])(?=-[0-9({\\[])", "0") + "#";
System.out.println(calculate(exp));
}
}
private static int calculate(String exp){
// 初始化栈
Stack<Integer> opStack = new Stack<>();
Stack<Character> otStack = new Stack<>();
// 整数记录器
String num = "";
for(int i = 0; i < exp.length(); i++){
// 抽取字符
char c = exp.charAt(i);
// 如果字符是数字,则加这个数字累加到num后面
if(Character.isDigit(c)){
num += c;
}
// 如果不是数字
else{
// 如果有字符串被记录,则操作数入栈,并清空
if(!num.isEmpty()){
int n = Integer.parseInt(num);
num = "";
opStack.push(n);
}
// 如果遇上了终结符则退出
if(c == '#')
break;
// 如果遇上了+-
else if(c == '+' || c == '-'){
// 空栈或者操作符栈顶遇到正括号,则入栈
if(otStack.isEmpty() || brace.contains(otStack.peek())){
otStack.push(c);
} else {
// 否则一直做弹栈计算,直到空或者遇到正括号为止,最后入栈
while(!otStack.isEmpty() && !brace.contains(otStack.peek()))
popAndCal(opStack, otStack);
otStack.push(c);
}
}
// 如果遇上*/
else if(c == '*' || c == '/'){
// 空栈或者遇到操作符栈顶是括号,或者遇到优先级低的运算符,则入栈
if(otStack.isEmpty()
|| brace.contains(otStack.peek())
|| otStack.peek() == '+' || otStack.peek() == '-'){
otStack.push(c);
}else{
// 否则遇到*或/则一直做弹栈计算,直到栈顶是优先级比自己低的符号,最后入栈
while(!otStack.isEmpty()
&& otStack.peek() != '+' && otStack.peek() != '-'
&& !brace.contains(otStack.peek()))
popAndCal(opStack, otStack);
otStack.push(c);
}
} else {
// 如果是正括号就压栈
if(brace.contains(c))
otStack.push(c);
else{
// 反括号就一直做弹栈计算,直到遇到正括号为止
char r = getBrace(c);
while(otStack.peek() != r){
popAndCal(opStack, otStack);
}
// 最后弹出正括号
otStack.pop();
}
}
}
}
// 将剩下的计算完,直到运算符栈为空
while(!otStack.isEmpty())
popAndCal(opStack, otStack);
// 返回结果
return opStack.pop();
}
private static void popAndCal(Stack<Integer> opStack, Stack<Character> otStack){
int op2 = opStack.pop();
int op1 = opStack.pop();
char ot = otStack.pop();
int res = 0;
switch(ot){
case '+':
res = op1 + op2;
break;
case '-':
res = op1 - op2;
break;
case '*':
res = op1 * op2;
break;
case '/':
res = op1 / op2;
break;
}
opStack.push(res);
}
private static char getBrace(char brace){
switch(brace){
case ')':
return '(';
case ']':
return '[';
case '}':
return '{';
}
return '#';
}
}
3、HJ108 正整数A和正整数B 的最小公倍数是指 能被A和B整除的最小的正整数值,设计一个算法,求输入A和B的最小公倍数。
import java.util.*;
public class Main{
public static int common(int a, int b){
if (b == 0) return a;
return a % b == 0 ? b : common(b, a%b);
}
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int b = sc.nextInt();
int com = common(a,b);
System.out.println(a*b/com);
sc.close();
}
}
思路:先求最大公约。忘了最大公约怎么求了(辗转相除),看了下题解发现了这个递归用法挺巧的。
4、HJ84 找出给定字符串中大写字符(即’A’-‘Z’)的个数。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str = sc.nextLine();
int count = 0;
for(int i=0;i<str.length();i++){
char c = str.charAt(i);
if(c>=65&&c<=90){
count++;
}
}
System.out.println(count);
}
sc.close();
}
}
常规思路做完,照例看一下骚操作。
import java.util.*;
public class Main{
public static void main(String[] arg){
Scanner s=new Scanner(System.in);
while(s.hasNextLine()){
String input1=s.nextLine();
String input=input1.replaceAll("([A-Z]+)","");
System.out.println(input1.length()-input.length());
}
}
}
用String.replaceAll("([A-Z]+)",""),把字符串中的大写字母消除,然后相减得出个数、
5、HJ61 把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。数据范围:0<=m<=10,1<=n<=10。本题含有多组样例输入。
import java.util.*;
public class Main{
public static int setApple(int m,int n){
if(m<0||n<=0){
return 0;
}
if(m==1||n==1||m==0){
return 1;
}
return setApple(m,n-1)+setApple(m-n,n);
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNextInt())
{
int m = sc.nextInt();
int n = sc.nextInt();
System.out.println(setApple(m,n));
}
sc.close();
}
}
每个事件可以分为f(m,n)=f(m-n,n)+f(m,n-1);f(m-n,n)是当苹果数大于等于盘子数的情况,f(m,n-1)是当苹果数小于盘子数的情况。当此事件分到苹果数为0或苹果数为1或盘子数为1的时候返回1,当苹果数小于0或盘子数小于等于0返回0。
6、HJ2 写出一个程序,接受一个由字母、数字和空格组成的字符串,和一个字母,然后输出输入字符串中该字母的出现次数。不区分大小写。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str = sc.nextLine().toLowerCase();
char c = sc.nextLine().toLowerCase().charAt(0);
System.out.println(nums(str,c));
}
public static int nums(String str,char c){
int i = 0;
char[] chars = str.toCharArray();
for(char ch:chars){
if(c == ch ){
i++;
}
}
return i;
}
}
我是用65-90,,97-122写的判断,这里学习了新方法:toLowerCase(),将字符串中的大写字母都转换成小写字母(同理也可用toUpperCase())。或者还可以用上面的String.replaceAll做减法。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String str =sc.nextLine().toLowerCase();
String s = sc.nextLine().toLowerCase();
System.out.print(str.length()-str.replaceAll(s,"").length());
sc.close();
}
}
7、HJ10 编写一个函数,计算字符串中含有的不同字符的个数。字符在ACSII码范围内(0~127),换行表示结束符,不算在字符里。不在范围内的不作统计。多个相同的字符只计算一次,例如,对于字符串abaca而言,有a、b、c三种不同的字符,因此输出3。
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
char[] c = sc.nextLine().toCharArray();
HashSet hs = new HashSet();
for(int i=0;i<c.length;i++){
if(c[i]>=0&&c[i]<=127){
hs.add(c[i]);
}
}
System.out.println(hs.size());
sc.close();
}
}
由于不统计重复字符,因此想到了set集合。set.size()获取集合中元素个数。