尝试AS的手机连接

1.我尝试进行手机连接电脑进行debug,但是我发现我找到的教程做到一半和我的手机配置后者是AS版本不同,不知道为什么IDE会报错不能连接手机。尝试了1.5h,令人烦躁。之后计划多创建几个项目作为备份使用,防止在创建项目时浪费很多时间。在这个过程中,我了解到了虚拟设备对内存的威胁,中间有几次我的程序运行到一半卡退了。还有就是,在运行项目时,一定要先build,再运行!
2.完成了石家庄站地铁的手机端收票计算。
在过程中,我发现站点信息输入错误,逐一进行了校验。之后,MainActivity.java的换乘逻辑错误,换乘时多加了一站。还有,在涉及换乘的站点计算时,换乘后的站点计算消失了,这样就会导致平白无故地少了几站,导致金额算错。下面是我修改上面问题之后的代码:
MainActivity.java

package com.example.myapplication3;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;

import java.util.*;

public class MainActivity extends AppCompatActivity {

    private Spinner startStation, endStation;
    private EditText ticketQuantity;
    private Button buyButton;
    private TextView resultText;

    private Map<String, List<String>> lines;
    private Map<String, String> stationToLine;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        startStation = findViewById(R.id.startStation);
        endStation = findViewById(R.id.endStation);
        ticketQuantity = findViewById(R.id.ticketQuantity);
        buyButton = findViewById(R.id.buyButton);
        resultText = findViewById(R.id.resultText);

        // 初始化地铁线路和站点
        initializeLinesAndStations();

        // 石家庄地铁站点列表,包含线路信息
        List<String> stationsWithLines = new ArrayList<>();
        for (Map.Entry<String, String> entry : stationToLine.entrySet()) {
            stationsWithLines.add(entry.getKey() + " (" + entry.getValue() + ")");
        }

        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, stationsWithLines);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

        startStation.setAdapter(adapter);
        endStation.setAdapter(adapter);

        buyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                calculateAndDisplayTicketPrice();
            }
        });
    }

    private void initializeLinesAndStations() {
        lines = new HashMap<>();
        stationToLine = new HashMap<>();

        // 1号线
        List<String> line1 = Arrays.asList("西王", "时光街", "长城桥", "和平医院", "烈士陵园", "新百广场", "解放广场", "平安大街", "北国商城", "博物馆", "体育场", "北宋", "谈固", "朝晖桥", "白佛", "留村", "火炬广场", "石家庄东站", "南村", "洨河大桥", "西庄", "东庄", "会展中心", "商务中心", "园博园", "福泽");
        lines.put("1号线", line1);
        for (String station : line1) {
            stationToLine.put(station, "1号线");
        }

        // 2号线
        List<String> line2 = Arrays.asList("柳辛庄", "庄窠·铁道大学", "义堂", "建和桥", "长安公园", "北国商城", "裕华路", "槐中路", "欧韵公园", "元村", "石家庄站", "塔坛", "仓丰路留村", "南位", "嘉华路");
        lines.put("2号线", line2);
        for (String station : line2) {
            stationToLine.put(station, "2号线");
        }

        // 3号线
        List<String> line3 = Arrays.asList("西三庄", "高柱", "柏林庄", "市庄", "市二中", "新百广场", "东里", "西三教", "石家庄站", "汇通路", "孙村", "塔冢", "东王", "南王", "位同", "东二环南路", "西仰陵", "中仰陵", "南豆", "太行南大街", "乐乡");
        lines.put("3号线", line3);
        for (String station : line3) {
            stationToLine.put(station, "3号线");
        }
    }

    private void calculateAndDisplayTicketPrice() {
        String startWithLine = startStation.getSelectedItem().toString();
        String endWithLine = endStation.getSelectedItem().toString();

        // 提取站点名称(去掉线路信息)
        String start = startWithLine.split(" \\(")[0];
        String end = endWithLine.split(" \\(")[0];

        String quantityStr = ticketQuantity.getText().toString();

        if (quantityStr.isEmpty()) {
            resultText.setText("请输入购票数量");
            return;
        }

        int quantity = Integer.parseInt(quantityStr);
        int distance = calculateShortestPath(start, end);
        int price = calculatePrice(distance);

        int totalPrice = price * quantity;

        resultText.setText("购票成功!总金额: " + totalPrice + "元");
    }

    private int calculateShortestPath(String start, String end) {
        if (!stationToLine.containsKey(start) || !stationToLine.containsKey(end)) {
            return -1;
        }

        Map<String, Integer> distances = new HashMap<>();
        Map<String, String> lineUsed = new HashMap<>();
        for (String station : stationToLine.keySet()) {
            distances.put(station, Integer.MAX_VALUE);
        }
        distances.put(start, 0);
        lineUsed.put(start, stationToLine.get(start));

        PriorityQueue<String> queue = new PriorityQueue<>(Comparator.comparingInt(distances::get));
        queue.add(start);

        while (!queue.isEmpty()) {
            String current = queue.poll();
            if (current.equals(end)) {
                break;
            }

            String currentLine = lineUsed.get(current);
            List<String> currentLineStations = lines.get(currentLine);

            // 找到当前站点在线路中的位置
            int currentIndex = currentLineStations.indexOf(current);
            if (currentIndex == -1) {
                continue; // 如果当前站点不在当前线路中,跳过
            }

            // 向前遍历(向线路的下一站)
            if (currentIndex < currentLineStations.size() - 1) {
                String nextStation = currentLineStations.get(currentIndex + 1);
                int newDistance = distances.get(current) + 1;
                if (newDistance < distances.get(nextStation)) {
                    distances.put(nextStation, newDistance);
                    lineUsed.put(nextStation, currentLine);
                    queue.add(nextStation);
                }
            }

            // 向后遍历(向线路的上一站)
            if (currentIndex > 0) {
                String prevStation = currentLineStations.get(currentIndex - 1);
                int newDistance = distances.get(current) + 1;
                if (newDistance < distances.get(prevStation)) {
                    distances.put(prevStation, newDistance);
                    lineUsed.put(prevStation, currentLine);
                    queue.add(prevStation);
                }
            }

            // 考虑换乘
            for (String line : lines.keySet()) {
                if (lines.get(line).contains(current) && !line.equals(currentLine)) {
                    // 换乘增加1站
                    int newDistance = distances.get(current) + 1;
                    List<String> transferLineStations = lines.get(line);
                    int transferIndex = transferLineStations.indexOf(current);
                    if (transferIndex == -1) {
                        continue; // 如果当前站点不在换乘线路中,跳过
                    }

                    // 向前遍历(向换乘线路的下一站)
                    if (transferIndex < transferLineStations.size() - 1) {
                        String nextTransferStation = transferLineStations.get(transferIndex + 1);
                        if (newDistance < distances.get(nextTransferStation)) {
                            distances.put(nextTransferStation, newDistance);
                            lineUsed.put(nextTransferStation, line);
                            queue.add(nextTransferStation);
                        }
                    }

                    // 向后遍历(向换乘线路的上一站)
                    if (transferIndex > 0) {
                        String prevTransferStation = transferLineStations.get(transferIndex - 1);
                        if (newDistance < distances.get(prevTransferStation)) {
                            distances.put(prevTransferStation, newDistance);
                            lineUsed.put(prevTransferStation, line);
                            queue.add(prevTransferStation);
                        }
                    }
                }
            }
        }

        return distances.get(end);
    }

    private int calculatePrice(int distance) {
        // 每3站收费1元,不足3站按1元收费
        return (distance + 2) / 3;
    }
}

布局代码:activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <Spinner
        android:id="@+id/startStation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/start_station_prompt" />

    <Spinner
        android:id="@+id/endStation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/end_station_prompt" />

    <EditText
        android:id="@+id/ticketQuantity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="购票数量"
        android:inputType="number" />

    <Button
        android:id="@+id/buyButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="立即购票" />

    <TextView
        android:id="@+id/resultText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="结果将显示在这里"
        android:textSize="18sp"
        android:gravity="center"
        android:padding="16dp" />
</LinearLayout>

3.实现单链表的中间位置插入和单链表的释放
代码如下:
对于链表释放的操作,有两种方法:指针站在自己删自己、指针站在表头依次向后删除
在这个过程中,不可避免的要生成一个临时指针进行备份。要注意的是,不能将指针p的值给临时指针,然后再释放p。因为从图上来看,p和临时指针只是指向一个相同的元素,不能代表那个元素本身。这样操作,临时指针指向的内容也会消失。还有就是,每释放一个节点,就对链表头的总数减去一。在执行这个操作时,有点类似于删除时的操作思想。

void releaseLinkList(LinkList_t* link_table) {

	//站在自己删自己
	//node_t* p = link_table->head.next;
	//node_t* tmp = malloc(sizeof(node_t));
	//while (p) {
	//	tmp = p->next;
	//	free(p);
	//	p = tmp;
	//	link_table->count--;//记得给个数相减
	//}


	//守住头结点,一直删除头结点后面的元素
	node_t* p = &link_table->head;//头结点的首地址
	node_t* tmp;
	while (p->next) {
		tmp = p->next;
		p->next = tmp->next;
		free(tmp);
		link_table->count--;
	}

	printf("number of node_t: %d\n", link_table->count);
}

void showLinkList(const LinkList_t* link_table) {
	//辅助指针指向第一个元素,辅助指针不断向后指,直到遇到NULL
	
	node_t* p = link_table->head.next;//指针类型等于指针类型,不应该多加“&”
	printf("link list: %d\n ", link_table->count);
	while (p) {
		printf("%d\t", p->val);
		p = p->next;
	}

	printf("\n");
}

在中间插入的代码:
1.注意传过来的位置pos是从0开始还是从1开始
2.判断pos传值的合法性,总不能大于链表节点的总数或者是负数
3.还是,找到待插入节点的前一个位置;此处,指针p和下标index关联起来,有助于判断p的位置
4.执行插入操作

int insertLinkListPos(LinkList_t* link_table, int pos, Element_t val) {
	//pos:[0...]
	if (pos < 0 || pos > link_table->count) {//可以等于,放到最后
		printf("insert pos invalid!\n");
		return -1;
	}
	node_t* p = &link_table->head;
	/*for (int i = 0; i < pos-1; i++) {
		p = p->next;
	}*/

	//找到索引pos-1的首地址
	int index = -1;
	while (p&&index<pos-1) {
        p = p->next;
		index++;
	}
	node_t* new_node = malloc(sizeof(node_t));
	
	new_node->val = val;
	new_node->next = p->next;
	p->next = new_node;
	link_table->count++;
	return 0;

}
posted @ 2025-03-16 22:00  f-52Hertz  阅读(16)  评论(0)    收藏  举报