CCF题目1—P1540 机器翻译

从今天开始刷算法题。

在这里插入图片描述
在这里插入图片描述

自己的思路:

 * 思路:
 * 先定义两个数组,将第一个数组的数据都定为-1;
 * 第二个数组存放数据,并定义一个指针指向0号索引;
 * 定义一个计数器;
 * 先检查有没有相同的,如果没有,当检查到数据为-1时,将数据替换-1;
 * 当没有-1数据时,遍历数组,寻找数组中是否已存在该数据,是则不做变化;
 * 否则数组前移1位,并把数据存入最后一位,计数器+1;

但是发现这种思路写起来,会有很大的局限性,比如数据量大了很繁琐,而且没用的代码量也比较多。

根据题意所以简略了一下思路:
判断是否存在该元素,是则使用continue跳过本次循环,否则对数组内的数据前移一位,最后一位赋值为新元素,并计数
同时,在编代码的过程中,由于不熟悉部分代码语法,还是通过百度了一下语法,并通过调试来输出显示。
调试显示测试过程是否正确其实这样虽然结果是正确的,但过程跟题目给的顺序是不一样的。

而且为了在网页上测试通过,还得严格按照网址上的格式进行修改才能通过编译。
在这里插入图片描述
以下是源代码:写的较差,仅供参考

package CCF.P1540;
//package CCF;
//package CCF;//day01——P1540——机器翻译

import java.util.Arrays;
import java.util.Scanner;

public class Main
{
	/*
	 * 需求:
	 * 两个数组,一个M,一个N;
	 * 前者定义一个数组大小,后者定义数据的个数;
	 * 遍历每个数据,当数组没满时,将数据存入数组;
	 * 当数组中存在该数据时不作改变;
	 * 当不存在时,将该数据替换数组最后一位
	 * 
	 * 思路:
	 * 先定义两个数组,将第一个数组的数据都定为-1;
	 * 第二个数组存放数据,并定义一个指针指向0号索引;
	 * 定义一个计数器;
	 * 先检查有没有相同的,如果没有,当检查到数据为-1时,将数据替换-1;
	 * 当没有-1数据时,遍历数组,寻找数组中是否已存在该数据,是则不做变化;
	 * 否则数组前移1位,并把数据存入最后一位,计数器+1;
	 * 
	 * 判断是否存在该元素,是则使用continue跳过本次循环,否则对数组内的数据前移一位,最后一位赋值为新元素。
	 */
	
	public static void main(String[] args) {
		//输入M,N;
		Scanner sc = new Scanner(System.in);
//		System.out.println("请输入M:");
		int M = sc.nextInt();
//		System.out.println("请输入N:");
		int N = sc.nextInt();
		
		//定义数组M
		int []MM = new int[M];
		for(int i=0;i<M;i++)
		{
			MM[i] = -1;
		}
		//定义数组N
		int []NN = new int[N];
//		System.out.println("请输入数据:");
		for(int i=0;i<N;i++)
		{
			NN[i] = sc.nextInt();
		}
		
//		System.out.println("M:"+Arrays.toString(MM));
//		System.out.println("N:"+Arrays.toString(NN));
		
		//定义计时器
		int count = 0;
		boolean flag = false;
		for(int j=0;j<N;j++)
		{
//			System.out.print("第"+j+"次:"+NN[j]+" : ");
			for(int k=0;k<M;k++)
			{
				if(NN[j]==MM[k])
				{
					flag = true;
					break;
				}
				flag = false;
			}
			if(flag==true)
			{
//				System.out.println("已存在");
				continue;
			}
			if(flag==false)
			{
				for(int k=0;k<M-1;k++)
				{
					MM[k]=MM[k+1];
				}
				MM[M-1] = NN[j];count++;
//				System.out.println("M:"+count+" : "+Arrays.toString(MM));
			}
		}
		
		System.out.println("M:"+Arrays.toString(MM));
		System.out.println("N:"+Arrays.toString(NN));
		System.out.println("需要查询:"+count+"次");
		System.out.println(count);
	}
}

可见性能优化封面还是比较差的,而且也只用到了数组的知识,测试了一下发现目前自己的代码能力还是比较差,需要多多学习和练习。

然后根据网上的代码发现了一种新的思路,用到了队列和数组判断,比我自己的思路更加灵活。

队列相关知识:

基于先进先出的方式:

  add      	  增加一个元索                    	 如果队列已满,则抛出一个IIIegaISlabEepeplian异常
  remove 		  移除并返回队列头部的元素   		 如果队列为空,则抛出一个NoSuchElementException异常
  element  	  返回队列头部的元素            	 如果队列为空,则抛出一个NoSuchElementException异常
  offer         添加一个元素并返回true       		 如果队列已满,则返回false
  poll          移除并返问队列头部的元素  		 如果队列为空,则返回null
  peek          返回队列头部的元素            	 如果队列为空,则返回null
  put           添加一个元素                       如果队列满,则阻塞
  take          移除并返回队列头部的元素     	     如果队列为空,则阻塞

思路:
可以看成一个队列的问题

检测队列中是否存在,可以使用一个p数组,长度为1001 因为题目要求0≤N≤1000 默认p数组每一个都为0,只要p[N]==0

就队列不存在这个元素,相当于一个map一一对应 N相当于p的下标 只要检测N作为下标所对应的数是否为0就可以检测是否存在

添加后p[N]++ 这时再有同样元素,就可以知道其不为0,所以不用翻字典

当队列达到满的时候,队头出来,队尾添加元素 这时候队头元素作为下标对应的p就应该–置0 并同时把p[队尾元素]++

同时设置一个检测队列是否满的值和翻字典的次数的值即可

package CCF.P1540;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/*
 * 思路:
可以看成一个队列的问题

检测队列中是否存在,可以使用一个p数组,长度为1001 因为题目要求0≤N≤1000 默认p数组每一个都为0,只要p[N]==0

就队列不存在这个元素,相当于一个map一一对应 N相当于p的下标 只要检测N作为下标所对应的数是否为0就可以检测是否存在

添加后p[N]++ 这时再有同样元素,就可以知道其不为0,所以不用翻字典

当队列达到满的时候,队头出来,队尾添加元素 这时候队头元素作为下标对应的p就应该--置0 并同时把p[队尾元素]++

同时设置一个检测队列是否满的值和翻字典的次数的值即可
 */
public class P1540 {
	public static void main(String[] args) {
		//键盘录入
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		
		//定义数组
		int a[] = new int[m];
		for(int i=0;i<m;i++)
		{
			a[i] = sc.nextInt();
		}
		
		//数组p判断是否存在该元素,默认设为0
		int p[] = new int [1001];
		//队列,先进先出
		Queue<Integer> my = new LinkedList<Integer>();
		int index = 0;
		int count = 0;
		
		for(int i=0;i<m;i++)
		{
			if(p[a[i]]==0)
			{
				if(index<n)
				{
					p[a[i]]+=1;
					my.add(a[i]);
					index++;
					count++;
				}
				else
				{
					p[my.poll()]-=1;//弹出队列的首部元素
					my.add(a[i]);//尾部添加新元素
					p[a[i]]+=1;//声明元素已存在
					count++;//计数
				}
			}
		}
		
		System.out.println(count);
	}
}

总结:

通过这次较小的编程,发现了自己的编码能力实在是较弱,所以以后还会多多练习,做到学练结合。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值