简易的浏览器历史记录系统
背景介绍
请你设计并实现一个简易的浏览器历史记录系统。这个系统需要模拟现代浏览器中的核心功能:访问新页面、后退、前进,并管理一个有容量上限的历史记录列表。
核心概念
-
浏览历史 (History List):
- 可以看作一个线性的页面访问序列。
- 例如:
[pageA, pageB, pageC, pageD]
-
当前页指针 (Current Page Pointer):
- 在任何时候,总有一个指针指向历史记录列表中的某个页面,这个页面就是用户当前正在浏览的页面。
back()操作会使该指针向列表的左侧(更早的记录)移动。forward()操作会使该指针向列表的右侧(更新的记录)移动。
-
历史容量 (History Capacity):
- 系统最多只能缓存
maxCount个历史记录。 - 如果在添加新页面后,历史记录总数超过了
maxCount,系统会自动删除最早的一条历史记录(即列表最左侧的条目)。
- 系统最多只能缓存
功能要求
你需要实现一个 BrowserHistorySys 类,支持以下操作:
BrowserHistorySys(string homepage, int maxCount)
-
功能: 系统初始化。
-
效果:
- 将
homepage作为第一个页面,放入浏览历史中。 - 设置历史记录的容量上限为
maxCount。 - 当前页指针指向
homepage。
- 将
visit(string url)
-
功能: 访问一个新的 URL。
-
规则:
-
如果
url与当前页相同,则不做任何操作。 -
如果 url 是一个新页面,则:
a. 清除前进记录: 丢弃当前页指针右侧的所有历史记录。
b. 添加新记录: 将 url 添加到历史记录的末尾(即当前页之后)。
c. 更新指针: 将当前页指针移动到这个新添加的 url 上。
d. 检查容量: 如果此时历史记录的总数超过了 maxCount,则从历史记录的最开头移除一个最旧的页面。
-
-
返回值: 返回操作完成后,浏览历史中的缓存页面总数量。
back()
- 功能: 在浏览历史中后退一步。
- 规则: 将当前页指针向左移动一个位置。
- 边界: 如果光标已经位于历史记录的最开头,则无法再后退,停留在原地。
- 返回值: 返回后退后所停留页面的 URL。
forward()
- 功能: 在浏览历史中前进一步。
- 规则: 将当前页指针向右移动一个位置。
- 边界: 如果光标已经位于历史记录的最后,则无法再前进,停留在原地。
- 返回值: 返回前进后所停留页面的 URL。
输入格式
homepage,url: 字符串,由小写字母、数字、.和/组成,长度[8, 32)。maxCount:0 < maxCount < 20。- 函数调用总次数不超过 1000 次。
输出格式
- 根据每个函数的原型要求返回相应的值。最终的整体输出由评测框架完成。
样例
输入样例 1
["BrowserHistorySys", "visit", "back", "forward", "forward", "visit", "visit", "back", "visit", "back", "visit"]
[["w3.huawei.com", 10], ["google.com"], [], [], [], ["baidu.com"], ["youtube.com"], [], ["baidu.com"], [], ["mails.huawei.com"]]
输出样例 1
[null, 2, "w3.huawei.com", "google.com", "google.com", 3, 4, "baidu.com", 4, "google.com", 3]
样例 1 执行流程详解
- 当前页用
*...*标记
| # | 调用 | 解释与系统状态变化 | 返回值 |
|---|---|---|---|
| 1 | BrowserHistorySys("w3.huawei.com", 10) | 初始化。历史记录: [*w3.huawei.com*] | null |
| 2 | visit("google.com") | 访问新页面。历史记录: ["w3.huawei.com", *"google.com"*]。大小为 2。 | 2 |
| 3 | back() | 后退一步。历史记录: [*w3.huawei.com*, "google.com"]。 | "w3.huawei.com" |
| 4 | forward() | 前进一步。历史记录: ["w3.huawei.com", *"google.com"*]。 | "google.com" |
| 5 | forward() | 已在历史记录末尾,无法前进,停留在原地。历史记录: ["w3.huawei.com", *"google.com"*]。 | "google.com" |
| 6 | visit("baidu.com") | 访问新页面,无前进记录可清除。历史记录: ["w3.huawei.com", "google.com", *"baidu.com"*]。大小为 3。 | 3 |
| 7 | visit("http://...") | 访问新页面。历史记录: ["w3.huawei.com", ..., *"http://..."*]。大小为 4。 | 4 |
| 8 | back() | 后退一步。历史记录: [..., "google.com", *"baidu.com"*, "http://..."]。 | "baidu.com" |
| 9 | visit("baidu.com") | 访问的 URL 与当前页相同,不做任何操作。历史记录和大小不变。 | 4 |
| 10 | back() | 后退一步。历史记录: [..., *"google.com"*, "baidu.com", "http://..."]。 | "google.com" |
| 11 | visit("mails.huawei.com") | 访问新页面。当前页为 google.com,其后的前进记录 ["baidu.com", "http://..."] 被清除。然后添加新页面。历史记录: ["w3.huawei.com", "google.com", *"mails.huawei.com"*]。大小为 3。 | 3 |
import java.util.ArrayList;
import java.util.List;
/**
* 模拟一个浏览器的历史记录系统.
* 该系统使用一个列表来存储浏览历史,并用一个指针来跟踪当前页面。
* 它支持访问新页面、后退和前进等核心功能。
*/
public class BrowserHistorySys {
// --- 系统状态变量 ---
/** 使用列表来存储浏览历史记录的URL. */
private final List<String> history;
/** 缓存的最大页面数量. */
private final int maxCount;
/** 一个整数索引,作为指针,指向 history 列表中当前页面的位置. */
private int currentIndex;
/**
* BrowserHistorySys(string homepage, int maxCount) -- 初始化系统.
* @param homepage 初始化的主页URL
* @param maxCount 浏览历史的最大缓存数量
*/
public BrowserHistorySys(String homepage, int maxCount) {
this.history = new ArrayList<>();
this.maxCount = maxCount;
// 初始时,将主页加入历史记录
this.history.add(homepage);
// 当前指针指向唯一的记录,即索引0
this.currentIndex = 0;
}
/**
* visit(string url) -- 跳转访问新页面.
* @param url 要访问的新页面的URL
* @return 操作后,浏览历史中的缓存页面数量
*/
public int visit(String url) {
// 获取当前页面的URL
String currentPage = this.history.get(this.currentIndex);
// 如果要访问的URL和当前页相同,则不做任何操作
if (url.equals(currentPage)) {
return this.history.size();
}
// --- 如果是新的URL,则执行以下操作 ---
// 1. 清除浏览历史中原当前页的所有“前进”记录。
// subList 创建了一个从 currentIndex+1 到列表末尾的视图,.clear() 操作会从原始列表中删除这些元素。
if (this.currentIndex < this.history.size() - 1) {
this.history.subList(this.currentIndex + 1, this.history.size()).clear();
}
// 2. 将新访问的URL添加到历史记录的末尾
this.history.add(url);
// 3. 检查缓存是否超出容量上限
if (this.history.size() > this.maxCount) {
// 如果超出,则移除历史记录中最早的一条(即列表的第一个元素)
this.history.remove(0);
}
// 4. 更新当前页指针。在访问新页面后,当前页总是历史记录中的最后一项。
// 这一步必须在可能发生的 remove(0) 操作之后执行,以确保索引正确。
this.currentIndex = this.history.size() - 1;
// 5. 返回当前历史记录的数量
return this.history.size();
}
/**
* back() -- 在浏览历史中后退一步.
* @return 后退后停留页面的URL
*/
public String back() {
// 检查是否还有后退的空间(即当前不是第一条记录)
if (this.currentIndex > 0) {
// 如果可以后退,则将指针向前移动一位
this.currentIndex--;
}
// 如果已无法后退,指针保持不变。
// 返回指针当前指向的页面的URL
return this.history.get(this.currentIndex);
}
/**
* forward() -- 在浏览历史中前进一步.
* @return 前进后停留页面的URL
*/
public String forward() {
// 检查是否还有前进的空间(即当前不是最后一条记录)
if (this.currentIndex < this.history.size() - 1) {
// 如果可以前进,则将指针向后移动一位
this.currentIndex++;
}
// 如果已无法前进,指针保持不变。
// 返回指针当前指向的页面的URL
return this.history.get(this.currentIndex);
}
}