#信息学奥赛一本通(1143)
#只有20分
首先先输入一个字符串,然后将它分割成一个个单词
int i=0,z=0,max=0,h,small=2000,d;
while((a[i++]=getchar())!='\n');
for(int o=0;o<500;o++)
{
if(a[o]==' '||a[o]==','||a[o]=='\n')
{
if(z>max) max=z,h=o;
if(z<small&&(a[o-1]!=' '&&a[o-1]!=',')) small=z,d=o;
z=0;
}
else
{
z++;
}
}
判断最长最短的单词,最后输出
for(int y=h-max;y<h;y++)
{
cout<<a[y];
}
cout<<endl;
for(int y=d-small;y<d;y++)
{
cout<<a[y];
}
有什么问题。
char a[] 初始化没?
第一个for循环,不要循环到 a 结束,只要循环到 i,后面都不是输入内容:
for(int o=0;o<i;o++)
1,接下来实现一个简单的单向链表,下面直接贴代码。
链类
public class Link {// 链类
private Node head;
// 初始化链表 相当于有了一个具体的火车头
public Link(Node head) {
this.head = head;
}
// 往链表中添加节点 就是加车厢
public void add(Node node) {
// 添加节点的时候就是往链表的尾部 添加
// 也就是说 我们要先找到最后一节车厢
Node p = head;
while (p.getNext() != null) {
p = p.getNext();
}
// 如果循环结束 那么p就是最后一个节点
// 将要加入的节点设置到p的下一个
p.setNext(node);
}
// 遍历节点
public void display() {
Node p = head.getNext();// 设置一个指针指向头结点的下一个
while (p != null) {
System.out.println(p.getData());
p = p.getNext();
}
}
// 得到节点的数量
public int size() {
int size = 0;
Node p = head.getNext();// 设置一个指针指向头结点的下一个
while (p != null) {
size++;
p = p.getNext();
}
return size;
}
// 插入节点
public boolean insert(String data, Node node) {
Node p1 = head;
Node p2 = head.getNext();
while (p2 != null) {
if (data.equals(p2.getData())) {
p1.setNext(node);// 设置前驱节点的下一个为要插入的节点
node.setNext(p2);// 设置当前要插入节点的下一个为后一个指针
return true;
}
// 循环增量
p1 = p2;
p2 = p2.getNext();
}
return false;
}
// 查询节点
// 按照指定的值查询节点是否存在
public boolean find(String data) {
Node p = head.getNext();// 指向头结点的下一个
while (p != null) {
if (p.getData().equals(data)) {
return true;
}
p = p.getNext();
}
return false;
}
// 删除节点 按照指定的数据删除节点
public boolean del(String data) {
// 声明一个指针指向链表的头结点
Node p = head;
while (p.getNext() != null) {
// 比较当前节点的下一个节点的值是否和我们要找的值相等
if (p.getNext().getData().equals(data)) {
p.setNext(p.getNext().getNext());// 设置p的下一个为p的下一个的下一个
return true;
}
p = p.getNext();
}
return false;
}
}
实体类
public class Node {
private String data;// 数据域
private Node next;// 链域
public Node() {
}
public Node(String data) {// 初始化节点类
this.data = data;
this.next = null;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
测试类
public class Test {
public static void main(String[] args) {
Node head = new Node("火车头");
Link l = new Link(head);
l.add(new Node("车厢1"));
l.add(new Node("车厢2"));
l.add(new Node("车厢3"));
l.add(new Node("车厢4"));
l.add(new Node("车厢5"));
l.add(new Node("车厢6"));
l.add(new Node("车厢7"));
l.display();
System.out.println("当前节点有:" + l.size() + "个");
boolean flag = l.del("车厢7");
System.out.println(flag);
l.display();
System.out.println("当前节点有:" + l.size() + "个");
boolean f = l.find("车厢2");
if (f) {
System.out.println("查询成功");
} else {
System.out.println("查询失败");
}
l.insert("车厢2", new Node("商务舱"));
l.display();
}
}
2,双向循环链表示例,实现了类似于LikedList的功能,接下来贴代码。
模仿linkList的类
public class DbLinkedList<T> {
// 定义内部类,用作链表的节点
private class Node<T> {
Node<T> pre; // 指向前一个节点
Node<T> next; // 指向后一个节点
T value; // 当前节点的值
public Node(T value, Node<T> next, Node<T> pre) {
this.value = value;
this.next = next;
this.pre = pre;
}
public String toString() {
return this.value + "";
}
}
private Node<T> header; // 定义头节点
private int size; // 定义链表的长度
public DbLinkedList() {
header = new Node<T>(null, null, null);// 空的头节点,用来区分双向循环链表的首尾
header.pre = header.next = header; // 双向循环链表,首尾相连
size = 0;
}
public DbLinkedList(Collection<? extends T> collection) {
this();
addAll(this.size, collection);
}
public boolean add(T value)// 在链表的尾巴上面加一个节点, 相当于在header节点前面加一个节点
{
return add(header, value);
}
public boolean add(int index, T value)// 指定index处加入节点
{
return add(entry(index), value);
}
public boolean remove(Object obj)// 删除指定value的节点
{
Node<T> node;
// 1. 从header.next往后遍历,再到header时结束
for (node = header.next; node != header; node = node.next) {
if (node.value == obj || (obj != null && obj.equals(node.value))) {
remove(node);
return true;
}
}
// 2.java.util.LinkedList实现,先区分null再遍历,个人感觉效率差不多呀,希望有人赐教
/*
* if(obj==null) { for(node = header.next; node!=header; node=node.next)
* { if(node.value == null) { remove(node); return true; } } } else {
* for(node = header.next; node!=header; node=node.next) { if(node.value
* == obj || obj.equals(node.value)) { remove(node); return true; } } }
*/
return false;
}
public T remove(int index)// 删除指定index节点
{
return remove(entry(index));
}
public boolean addAll(Collection<? extends T> collection) {
return addAll(this.size, collection);
}
// 在指定index位置添加collection里的所有元素
public boolean addAll(int index, Collection<? extends T> collection) {
if (collection == null || collection.size() == 0) {
return false;
}
// 获取指定位置节点,如果index==size,则在末尾添加节点,即header节点之前
// 当index==size时,调用entry方法会抛异常,所以三则表达式很有必要
Node<T> node = index == this.size ? this.header : entry(index);
Object[] objArray = collection.toArray();
int len = objArray.length;
Node<T> preNode = node.pre;
for (int i = 0; i < len; i++) {
// 新建一个节点,新节点的next指向node,新节点的pre指向node的pre
// 完成指向过程node.pre←newNode→node
// 当第二次迭代时,preNode=newNode1(i=1创建的newNode),
// newNode1←newNode2(i=2创建的newNode)→node
Node<T> newNode = new Node<T>((T) objArray[i], node, preNode);
// 维持双向链表的指向,将node的pre节点的next指向新节点,完成指向过程node.pre→newNode
// 当第二次迭代时,newNode1→newNode2
preNode.next = newNode;
// 将preNode指向newNode,当第二次迭代时,preNode往后移动一位
preNode = newNode;
}
// 迭代完成后,node的前一个节点指向preNode(即最后一次创建的newNode),preNode←node
// 如果len=2,完成的链就变成这样preNode→←newNode1→←newNode2→←node
node.pre = preNode;
// 长度加len
this.size += len;
return true;
}
private T remove(Node<T> node) {
// node的前一个节点next指向node的下一个节点
// node的下一个节点pre指向node的前一个节点
// A→node←B改成A→←B
node.pre.next = node.next;
node.next.pre = node.pre;
// node的前后指向null
// A←node→B改成null←node→null
node.pre = node.next = null;
T value = node.value;
node.value = null;
this.size--;
return value;
}
public T get(int index) {
return entry(index).value;
}
private Node<T> entry(int index) // 迭代至index处的节点
{
rangeIndex(index); // 判断index是否越界
Node<T> node = this.header;
// 判断index是否小于size的一半,如果小于就从header往后开始迭代,否则就从header往前开始迭代,提高效率
// 例如有一个链表header→A→B→C→D→header
if (index < (this.size >> 1)) {
// 因为header是空的头节点,所以i要小于等于index
// 例如index=1, 小于size的一半2
// i=0时,node=A
// i=1时,node=B,然后跳出循环
for (int i = 0; i <= index; i++) {
node = node.next;
}
} else {
// 例如index=2,不小size的一半
// i=3, node等于header的前一个, node=D
// i=2, node=C,然后跳出循环
for (int i = this.size - 1; i >= index; i--) {
node = node.pre;
}
}
return node;
}
private void rangeIndex(int index) {
if (index < 0 || index >= this.size) {
throw new IndexOutOfBoundsException("index错误");
}
}
private boolean add(Node<T> node, T value) {
// 新建一个节点,新节点的next指向node,新节点的pre指向node的pre
// 完成指向过程node.pre←newNode→node
Node<T> newNode = new Node<T>(value, node, node.pre);
// 维持双向链表的指向,将node的pre节点的next指向新节点,完成指向过程node.pre→newNode
node.pre.next = newNode;
// node节点的前一个节点指向新节点,完成指向过程newNode←node
node.pre = newNode;
// 上面两行代码不能颠倒,否则node的前一个节点会被覆盖成新节点,会丢失node原来的前一个节点的next指向
// 上述代码完成了在node节点和node前一个节点之间加入一个新节点,并维护了双向关系
this.size++;
return true;
}
public void clear() {
Node<T> node = header.next;
// 将每一个节点的双向指向都清空,这样每个节点都没有被引用,可以方便垃圾回收器回收内存
while (node != header) {
// 将node的下一个节点临时保存起来
Node<T> tempNode = node.next;
// 将node的下一个节点和上一个节点置空
node.next = node.pre = null;
// 将node的值也置空
node.value = null;
// 将node移动到下一个节点
node = tempNode;
}
// 清空header的双向指向null
this.header.next = this.header.pre = this.header;
this.size = 0;
}
public boolean isEmpty() {
return this.size == 0;
}
public int size() {
return this.size;
}
}
抱歉,需要提供具体的问题才能给出相关代码和解决方案。参考资料中提供了一些关于数据结构和算法的知识点,可以用来回答一些和数据结构或算法相关的问题。如果您有具体的问题需要解决,请提供相关信息。