剑指Offer面试题(第十四天)面试题20、21

 * 面试题20:表示数值的字符串


     * 题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)
     * 例如:字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值
     *     但“12e”、“1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是。
     * 
     * 思路:数值表示为  A[.B][e|E C]   或        [+|-].[B][e|E C]
     *     []此部分可有可无   A整数部分(0-9正负)    B小数部分(0-9)   C指数部分 (0-9正负)
     * 其中0-9的ASCII码是:48,49,50,51,52,53,54,55,56,57
     * 统计 e和E的个数 ,都不能超过1;并且对不同分情况:1、若字符你是E  2、若字符是.  3、若字符是0-9  4、若字符是其他非数值字符且不是E|e
 

package Test;

public class No20isNumeric {

	/*
	 * 面试题20:表示数值的字符串
	 * 题目:请实现一个函数用来判断字符串是否表示数值(包括整数和小数)
	 * 例如:字符串“+100”、“5e2”、“-123”、“3.1416”及“-1E-16”都表示数值
	 * 	但“12e”、“1a3.14”、“1.2.3”、“+-5”及“12e+5.4”都不是。
	 * 
	 * 思路:数值表示为  A[.B][e|E C]   或        [+|-].[B][e|E C]
	 * 	[]此部分可有可无   A整数部分(0-9正负)    B小数部分(0-9)   C指数部分 (0-9正负)
	 * 其中0-9的ASCII码是:48,49,50,51,52,53,54,55,56,57
	 * 统计 e和E的个数 ,都不能超过1;并且对不同分情况:1、若字符你是E  2、若字符是.  3、若字符是0-9  4、若字符是其他非数值字符且不是E|e
	 * 
	 * */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		No20isNumeric s = new No20isNumeric();
		
		char[] str = {'e','1','1'};
		
		for(int i = 0; i < str.length;i ++) {
			System.out.print(str[i]);
		}
		if(s.isNumeric(str)) {
			System.out.println("这个字符串表示数值(包括整数和小数)!");
		}
		else
			System.out.println("这个字符串不表示数值(包括整数和小数)!");
		
		 
	}

	public boolean isNumeric(char[] str) {
		// TODO Auto-generated method stub
		if(str == null) {
			return false;
		}
		
		int index = 0;
		//ecount  统计E的个数
		int ecount = 0;
		//E和.的个数都不能超过1
		//point  统计.的个数 
		int point = 0;
		//若第一个是正负号,则跳过
		if(str[0] == '-'|| str[0] == '+') {
			index ++;
		}
		
		for(int i = index;i < str.length;i ++ ) {
			if(str[i] == '-' || str[i] == '+') {
				//因为前面判断整数部分是否有正负号了,所以此处若出现正负号,则前一位是e或者E才是数值形式
				if(str[i-1] != 'e' && str[i-1] != 'E') {
					return false;
				}
				continue;
			}
			if(str[i] > 47 && str[i] < 58) {
				continue;
			}
			//首先确保E的个数不能大于1;其次要保证E前面和后面都要有数字,不能直接就是E;
			//还要确保e|E前面有数字0-9
			if(str[i] == 'e' || str[i] == 'E' ) {
				ecount++;  
				if(ecount>1) {
					return false;
				}
				//此处i = str.length 表示E不能为最后一个
				if(i == 0 || i == str.length-1 ||str[i-1] > 57 ||str[i-1] < 48) {
					return false;
				}
				continue;
			}
			
			if(str[i] == '.') {
				point++;
				if(point > 1) {
					return false;
				}
				continue;
			}
			
			//若是出现非数字且不是e|E,则返回false(小数点和符号用continue跳过了)
			if((str[i] < 48||str[i] > 57) && (str[i] != 'e' || str[i] != 'E')) {
				return false;
			}
			
			
		}
		return true;	
		
	}

}

 * 面试题21:调整数组顺序使奇数位于偶数前面


     * 题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
     * 使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分
     * 
     * 思路:
     * 方法一:设置两个指针  一个指向第一个元素,一饿指向最后一个元素
     * 第一个元素找偶数,第二个元素找奇数,然后二者进行交换即可。不能保证奇数之间的相对位置+偶数之间的相对位置
     * 
     * 方法二:设置一个LinkedList集合,将偶数存入其中,遍历完整个数组之后再将集合中的数据存入数组即可。
 

package Test;

import java.util.LinkedList;
import java.util.Scanner;

public class No21adjustOddEvent {

	/*
	 * 面试题21:调整数组顺序使奇数位于偶数前面
	 * 题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,
	 * 使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分
	 * 
	 * 思路:
	 * 方法一:设置两个指针  一个指向第一个元素,一饿指向最后一个元素
	 * 第一个元素找偶数,第二个元素找奇数,然后二者进行交换即可。不能保证奇数之间的相对位置+偶数之间的相对位置
	 * 
	 * 方法二:设置一个LinkedList集合,将偶数存入其中,遍历完整个数组之后再将集合中的数据存入数组即可。
	 * 
	 * 
	 * */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		No21adjustOddEvent  a = new No21adjustOddEvent();
		Scanner in = new Scanner(System.in);
		
		System.out.println("输入要构建的数组大小n:");
		int n = in.nextInt();
		System.out.println("输入一个有"+n+"个数据的整形数组:");
		int[] array = new int[n];		
		for(int i = 0;i < n;i++) {
			array[i] = in.nextInt();
		}
		
		//方法一:未考虑偶数之间的相对位置+奇数之间的相对位置
		//a.adjustOddEvent(array);
		//方法二:考虑奇数之间的相对位置+偶数之间的相对位置
		a.adjustOddEvent_relative(array);
	}


	//方法一:调整数组,使得奇数在前,偶数在后
	//运用两个指针进行头尾遍历,第一个指针指向头,第二个指针指向尾部
	//第一个指针向后寻找偶数,第二个指针向前寻找奇数,然后进行交换即可,但是相对位置没有保障。
	public void adjustOddEvent(int[] array) {
		// TODO Auto-generated method stub
		if(array == null || array.length == 0) {
			return ;
		}
		
		//开始指针  结束指针
		int begin = 0;
		int end = array.length - 1;
		
		//若begin>end  则表示遍历完数组了 两个指针相遇了
		while(begin < end) {
			//从头向后找第一个偶数
			while(begin < end && array[begin] % 2 != 0) 
				begin ++;
			
			//从尾向后找第一个奇数
			while(begin < end && array[end] % 2 != 1 )
				end --;
			
			//交换奇数和偶数的值
			if(begin < end) {
				int temp = array[begin];
				array[begin] = array[end];
				array[end] = temp;
				
			}
			
		}
		
		
		//输出数组的调整后的结果
		System.out.println("输入奇数在前偶数在后调整后的数组:");		
		for(int i = 0;i < array.length;i++) {
			System.out.print(array[i]+"   ");
		}
		
	}
	
	//方法二:空间复杂度O(n)  时间复杂度O(n)   
	//使用额外的空间将  偶数存入 ,并在遍历完数组后,将数据在存回数组即可
	//相对位置有保障
	public void adjustOddEvent_relative(int[] array) {
		// TODO Auto-generated method stub
		if(array == null || array.length == 0) {
			return ;
		}
		LinkedList<Integer> list = new LinkedList<>();
		int index = 0;
		for(int val:array) {
			//奇数  存在array数组中
			if((val % 2) == 1){
				array[index++] = val;
			}
			//偶数   存在list中
			else {
				list.add(val);
			}
			
		}
		
		//若index未达到数组尾部,则证明还有偶数没有存入,则将数据存入数组array即可
		while(index != array.length) {
			array[index++] = list.removeFirst();
		}
		
		
		//输出数组的调整后的结果
		System.out.println("输入奇数在前偶数在后调整后的数组:");		
		for(int i = 0;i < array.length;i++) {
			System.out.print(array[i]+"   ");
		}
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_43137176/article/details/89066589